红黑树插入删除调整

#include <stdio.h>

typedef struct RB{
    /* data */
    int val;
    struct RB *left;
    struct RB *right;
    //红色是1 黑色0
    int color;
    struct RB *parent;
}RB;

RB *root;

void leftRotate(RB *p){
    if(p != NULL){
        //记录p的右儿子
        RB *rightkid = p->right;
        //1.空出右儿子的左子树
        p->right = rightkid->left;
        //左子树不为空,需要更新父节点
        if(rightkid->left!= NULL){
                rightkid->left->parent = p;
        }
        //空出p的父节点
        rightkid->parent = p->parent;
        //父节点指向右儿子
        if(p->parent == NULL){
            //如果p是根节点
            root = rightkid;
        }
        else if(p == p->parent->left){
            //如果p在左边
            //右儿子成为父节点的左儿子
            p->parent->left = rightkid;
        }
        else{
            p->parent->right = rightkid;
        }
        // 3.右儿子和节点p会师,节点p成为左子树
        rightkid->left = p;
        p->parent = rightkid;
    }
}

void rightRotate(RB *p){
    if(p != NULL){
        //记录p的左儿子
        RB *leftkid = p->left;

        //1.空出p的左儿子的右子树
        p->left = leftkid->right;
        //右子树不为空,则更新他的父节点
        if(leftkid->right != NULL){
            leftkid->right->parent = p;
        } 

        //2.空出节点p的父节点
        leftkid->parent = p->parent;
        //父节点指向左儿子
        if(p->parent == NULL){
            root = leftkid;
        }
        else if(p->parent->left == p){
            //如果是左儿子
            p->parent->left = leftkid;
        }
        else{
            p->parent->right = leftkid;
        }

        //3.顺利会师
        leftkid->right = p;
        p->parent = leftkid;
    }
}

RB *parentOf(RB* p){
    return (p == NULL?NULL:p->parent);
}

void FixAfterInsert(RB *x){
    //默认1是红色 黑0
    x->color = 1;
    //P不为空,不是整棵树的根节点,父亲为红色,需要调整
    while(x != NULL && root != x && x->parent->color == 1){
        //父亲是祖父的左儿子
        if(parentOf(x) == parentOf(parentOf(x))->left){
            RB *uncle = parentOf(parentOf(x))->right;
            //父亲和叔叔都是红色
            if(uncle->color == 1){
                //父亲和叔叔都变成黑色
                parentOf(x)->color = 0;
                uncle->color = 0;
                //祖父变成红色,继续从祖父开始调整
                parentOf(parentOf(x))->color = 1;
                x = parentOf(parentOf(x));
            }
            //叔叔是黑色
            //叔父异色,自己是左儿子,进行R操作
            //叔父异色,自己是右儿子,父亲成为新的X,
            //对父亲执行左旋,在执行右旋
            else{
                //自己是父亲的右儿子,需要对父亲左旋
                if(x == parentOf(x)->right){
                    x = parentOf(x);
                    leftRotate(x);
                }
                //自己是父亲的左儿子,变色后右旋
                parentOf(x)->color = 0;
                parentOf(parentOf(x))->color = 1;
                rightRotate(parentOf(parentOf(x)));
            }
        }
        //父亲是祖父的右儿子
        else{
            RB *uncle = (parentOf(parentOf(x))->left);
            //父叔同为红色,只需要进行颜色调整
            if(uncle->color == 1){
                //叔父都变成黑色
                parentOf(x)->color = 0;
                uncle->color = 0;
                //祖父变为红色,从祖父开始调整
                parentOf(parentOf(x))->color = 1;
            }
            //叔父异色,自己是左儿子,进行RL操作
            //自己是右儿子,进行L操作
            else{
                if(parentOf(x)->left == x){
                    x = parentOf(x);
                    rightRotate(x);
                }
                //自己是父亲的右儿子,变色后左旋
                parentOf(x)->color = 0;
                parentOf(parentOf(x))->color = 1;
                leftRotate(parentOf(parentOf(x)));
            }
        }
    }
    //最后将根节点置为黑色
    root->color = 0;
}

void FixAfterDeletion(RB *x){
    //x不是根节点而且颜色为黑色,开始循环调整
    while(x != root && x->color == 0){
        //如果x是父亲的左儿子
        if(x == parentOf(x)->left){
            RB *brother = parentOf(x)->right;
            //如果兄弟为红色
            if(brother->color == 1){
                //兄弟变成黑色。父节点变成红色
                brother->color = 0;
                parentOf(x)->color = 1;
                //父节点左旋,恢复左子树的黑色高度
                leftRotate(parentOf(x));
                //更新兄弟
                brother = parentOf(x)->right;
            }

            //兄弟为黑色,左右侄子都为黑色
            if(brother->left->color == 0 &&brother->right->color == 0){
                //兄弟变成红色
                brother->color == 0;
                //从父节点开始调整
                x = parentOf(x);
            }
            else{
                //右侄子为黑色,左侄子为红色
                if(brother->right->color == 0){
                    //左侄子变为黑色,兄弟变为红色
                    brother->left->color = 0;
                    brother->color = 1;
                    //兄弟右旋 恢复右子树黑色高度
                    rightRotate(brother);
                    //左侄子成为新的兄弟
                    brother = parentOf(x)->right;
                }
                //右侄子为红色,兄弟变成父节点颜色
                brother->color = parentOf(x)->color;
                //父节点和右侄子变成会黑色
                parentOf(x)->color = 0;
                brother->right->color = 0;
                //父节点左旋
                leftRotate(parentOf(x));
                //x指向根节点
                x = root;
            }
        }
        //如果是父亲的右儿子
        else{
            RB *brother = parentOf(x);
            //兄弟为红色
            if(brother->color == 1){
                //兄弟变黑色,父亲变红色
                brother->color  = 0;
                parentOf(x)->color = 1;
                //父亲右旋,恢复红黑色高度
                rightRotate(parentOf(x));
                //更新兄弟为右侄子
                brother = parentOf(x)->left;
            }

            //兄弟的左右儿子为黑色
            if(brother->right->color == 0 && brother->left->color == 0){
                //兄弟变为红色
                brother->color = 1;
                //x指向父节点,继续调整
                x = parentOf(x);
            }
            else{
                if(brother->left->color == 0){
                    //右侄子变成黑色,兄弟变为红色
                    brother->right->color = 0;
                    brother->color = 1;
                    //对兄弟左旋
                    leftRotate(brother);
                    //右侄子成为新的兄弟
                    brother = parentOf(x)->left;
                }

                //左侄子为红色,兄弟改为父节点颜色
                brother->color = parentOf(x)->color;
                //父节点和左侄子变成黑色
                brother->left->color = 0;
                parentOf(x)->color = 0;
                //兄弟结点上提
                rightRotate(parentOf(x));
                x = root;
            }
        }
    }
    x->color = 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值