红黑树---插入调整


基调

只有当插入节点的父节点是红色,才需要调整


一、情况

情况1

状态:当前节点的叔节点也是红色
解决方案:
1. 将父节点设为黑色
2. 将叔节点设为黑色
3. 将祖父节点设为红色
4. 将祖父节点设为当前节点(之后继续对当前节点操作)


情况2

状态:(父节点是左子节点)当前节点的父节点是红色,叔节点是黑色,且当前节点是其父节点的右孩子
解决方案:
1.将父节点作为新的当前节点
2.以新的当前节点为支点进行左旋


情况3

状态:(父节点是左子节点)当前节点的父节点是红色,叔叔节点是黑色,且当前节点是其父节点的左孩子
解决方案:
1.将父节点设为黑色
2.将祖父节点设为红色
3.以祖父节点为支点进行右旋


情况4

状态:(父节点是右子节点)当前节点的父节点是红色,叔叔节点是黑色,且当前节点是其父节点的左孩子
解决方案:
1.将父节点作为新的当前节点
2.以新的当前节点为支点进行右旋


情况5

状态:(父节点是右子节点)当前节点的父节点是红色,叔节点是黑色,且当前节点是其父节点的右孩子
解决方案:
1将父节点设为黑色
2.将祖父节点设为红色
3.以祖父节点为支点进行左旋


二、代码

1.当前点的父节点为左子节点

使用解决方案:情况1 else (情况2 + 情况3)

rbtree_node * y = z->parent->parent->right;//z父节点的兄弟节点
if (y->color == RED){
    //情况1
    z->parent->color = BLACK;
    y->color = BLACK;
    z->parent->parent->color = RED;
    z = z->parent->parent;
}else{
    if (z == z->parent->right){
        //情况2
        z = z->parent;
        rbtree_left_rotate(T, z);
    }
    //情况3
    z->parent->color = BLACK;
    z->parent->parent->color = RED;
    rbtree_right_rotate(T, z->parent->parent);
}

2.当前点的父节点为右子节点

使用解决方案:情况1 else (情况4 + 情况5)

rbtree_node *y = z->parent->parent->left;
if (y->color == RED){
    //情况1
    z->parent->color = BLACK;
    y->color = BLACK;
    z->parent->parent->color = RED;
    z = z->parent->parent;
}else{
    if (z == z->parent->left){
        // 情况4
        z = z->parent;
        rbtree_right_rotate(T, z);
    }
    //情况5
    z->parent->color = BLACK;
    z->parent->parent->color = RED;
    rbtree_left_rotate(T, z->parent->parent);
}

总结

第一步:如果插入点的父节点是黑色,则不需要往下执行,如果插入点的父节点是红色,继续执行

第二步:如果叔节点是红色,直接变色,把祖父节点作为当前节点

第三步:
左(父节点相对祖父节点位置)右(当前节点相当于父节点的位置)为先左旋 然后 右旋
左左为 右旋
右右为 左旋
右左为 右旋 然后 左旋

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值