美文网首页
整理笔记[红黑树]

整理笔记[红黑树]

作者: 六十年目裁判长亚玛萨那度 | 来源:发表于2019-02-24 15:16 被阅读0次

    红黑树的其实就是加了操作的AVL树,这一类的树形结构,主要区别就是调整维护,删除维护的策略不同。

    因为红黑树的情况是高度对称的,那么所有的情况都能压缩一半。

    插入操作

    插入简单,主要难点在于插入操作的维护,插入操作需要维护的是什么呢?
    站在插入点的祖父点看,插入点和插入点的父亲都是红色,这个时候就需要盘它。

    插入情况

    你插入点在4,5,6,7。并且他爹是红色(8种情况)。那就盘(tiao)它(zheng)。
    如果他爹是黑色,黑点下插红点,满足条件,不调。

    插入与插入调整操作
    RBTNode *insert_maintain(RBTNode *root) {//插入策略
        if (!has_red_child(root)) return root;
        if (root->lchild->color == 0 && root->rchild->color == 0) {
            if (has_red_child(root->lchild) || has_red_child(root->rchild)) {
                root->color = 0;
                root->lchild->color = root->rchild->color = 1;
            }
            return root;
        } else if (root->lchild->color == 0 && has_red_child(root->lchild)) {
            if (root->lchild->rchild->color == 0) {
                root->lchild = left_rotate(root->lchild);
            }
            root = right_rotate(root);
        } else if (root->rchild->color == 0 && has_red_child(root->rchild)) {
            if (root->rchild->lchild->color == 0) {
                root->rchild = right_rotate(root->rchild);
            }
            root = left_rotate(root);
        } else {
            return root;
        }
        root->color = 0;
        root->lchild->color = root->rchild->color = 1;
        return root;
    }
    
    
    RBTNode *__insert(RBTNode *root, int key) {// 插入
        if (root == NIL) return init(key);
        if (root->key == key) return root;
        else if (root->key < key) root->rchild = __insert(root->rchild, key);
        else root->lchild = __insert(root->lchild, key);
        return insert_maintain(root);
    }
    
    RBTNode *insert(RBTNode *root, int key) {
        root = __insert(root, key);
        root->color = 1;
        return root;
    }
    
    
    

    删除操作:

    删除的策略:为了调整和少操作,在删除点以后,不管这给点是什么颜色,直接把删除点的颜色叠加到他爹的点上,这样他爹的颜色就是1,2,这两种,然后需要维护的是颜色出现有2的情况。

    删除的时候分为三种大情况:
    1.删除点的度为2
    2.删除点的度为1
    3.删除点的度为0

    删除度2,1,0:找前驱或者后继,交换值,删掉前驱后继
    因为是一层一层下去的,递归回去的时候一层一层的维护。

    删除的维护:

    删除的情况

    这个时候的关键点是双重黑点的兄弟点,1和4点爱是什么颜色就是什么颜色,因为不影响所以不确定。

    1.双重黑的2点的兄弟点是红色(如图此时是3点),那么来一个以双重黑2点的父亲为根节点(此时是1)开始的右旋,调整后让3为根节点,3点改成黑色,然后这个时候2点的父亲是1点,在1点看,看1点的左儿子(2点的兄弟)是不是黑色,不是就继续调整,直到进入第2步。

    2.双重黑的2点的兄弟点是黑色(如图此时是3点):

    • 双重黑点(根节点左儿子)的兄弟节点右儿子(根节点右儿子的右儿子)的(3点的右儿子)是黑色,那么以3点右旋,4点成为3的父亲,3点变成红色,双重黑的父亲左旋,4变成根节点,4点颜色变成双重黑父亲颜色,双重黑父亲颜色变成黑色,双重黑颜色减去一层
    • 双重黑点(根节点左儿子)的兄弟节点右儿子(根节点右儿子的右儿子)的(3点的右儿子)是红色,那么以3点父亲为root,左旋3点成为根节点,3点颜色变成双重黑父亲颜色,双重黑父亲颜色变成黑色,双重黑颜色减去一层

    删除与删除调整操作:

    RBTNode *erase_maintain(RBTNode *root) { // 删除策略
        if (root->lchild->color != 2 && root->rchild->color != 2) return root;
        #define UNFINE(a, b) (root->a->color == 2 && root->b->color == 1 && !has_red_child(root->b)) 
        if (UNFINE(lchild, rchild) || UNFINE(rchild, lchild)) {
            root->color += 1;
            root->lchild->color -= 1;
            root->rchild->color -= 1;
            return root;
        }
        #undef  UNFINE
        if (root->lchild->color == 2) {
            if (root->rchild->color == 0) {
                root = left_rotate(root);
                root->color = 1;
                root->lchild->color = 0;
                root->lchild = erase_maintain(root->lchild);
                return root;
            }
            root->lchild->color = 1;
            if (root->rchild->rchild->color != 0) {
                root->rchild = right_rotate(root->rchild);
                root->rchild->color = 1;
                root->rchild->rchild->color = 0;
            }
            root = left_rotate(root);
            root->color = root->lchild->color;
        } else {
            if (root->lchild->color == 0) {
                root = right_rotate(root);
                root->color = 1;
                root->rchild->color = 0;
                root->rchild = erase_maintain(root->rchild);
                return root;
            }
            root->rchild->color = 1;
            if (root->lchild->lchild->color != 0) {
                root->lchild = left_rotate(root->lchild);
                root->lchild->color = 1;
                root->lchild->lchild->color = 0;
            }
            root = right_rotate(root);
            root->color = root->rchild->color;
        }
        root->lchild->color = root->rchild->color = 1;
        return root;
    }
    
    RBTNode *__erase(RBTNode *root, int key) { // 删除
        if (root == NIL) return NIL;
        if (root->key < key) root->rchild = __erase(root->rchild, key);
        else if (root->key > key) root->lchild = __erase(root->lchild, key);
        else {
            if (root->lchild != NIL && root->rchild != NIL) {
                RBTNode *temp = preacessor(root);
                root->key = temp->key;
                root->lchild = __erase(root->lchild, temp->key);
            } else {
                RBTNode *temp = (root->lchild == NIL ? root->rchild : root->lchild);
                temp->color += root->color;
                free(root);
                return temp;
            }
        }
        return erase_maintain(root);
    }
    
    RBTNode *erase(RBTNode *root, int key) {
        root = __erase(root, key);
        root->color = 1;
        return root;
    } 
    

    其他结构操作:

    typedef struct RBTNode {
        int key;
        int color;
        struct RBTNode *lchild, *rchild;
    } RBTNode;
    
    
    RBTNode *NIL;
    __attribute__((constructor))
    void init_NIL() {
        NIL = (RBTNode *)malloc(sizeof(RBTNode));
        NIL->key = 0;
        NIL->color = 1;
        NIL->lchild = NIL->rchild = NIL;
    }
    
    RBTNode *init(int key) {
        RBTNode *q = (RBTNode *)malloc(sizeof(RBTNode));
        q->key = key;
        q->color = 0;
        q->lchild = q->rchild = NIL;
        return q;
    }
    
    RBTNode *left_rotate(RBTNode *root) {
        RBTNode *temp = root->rchild;
        root->rchild = temp->lchild;
        temp->lchild = root;
        return temp;
    }
    
    RBTNode *right_rotate(RBTNode *root) {
        RBTNode *temp = root->lchild;
        root->lchild = temp->rchild;
        temp->rchild = root;
        return temp;
    }
    
    int has_red_child(RBTNode *root) {
        return root->lchild->color == 0 || root->rchild->color == 0;
    }
    
    RBTNode *preacessor(RBTNode *root) {
        RBTNode *temp = root->lchild;
        while (temp->rchild != NIL) temp = temp->rchild;
        return temp;
    }
    
    void  clear(RBTNode *root) {
        if (root == NIL) return ;
        clear(root->lchild);
        clear(root->rchild);
        free(root);
        return ;
    }
    
    

    相关文章

      网友评论

          本文标题:整理笔记[红黑树]

          本文链接:https://www.haomeiwen.com/subject/ojyvyqtx.html