【简易版tinySTL】 红黑树-删除

image-20240627115018675

兄弟至少一个红孩子

LL

  1. 变色:首先r结点的颜色变为s结点的颜色,然后s结点的颜色变为p结点的颜色,最后p结点的颜色变为黑色
  2. 对p结点进行右旋
  3. 双黑变单黑

image-20240627114905644

RR

与LL型相同

  1. 变色:首先r结点的颜色变为s结点的颜色,然后s结点的颜色变为p结点的颜色,最后p结点的颜色变为黑色
  2. 对p结点进行左旋
  3. 双黑变单黑

image-20240627114925391

LR、RL

LR、RL二者差不多

LR:

  1. 首先r结点的颜色变为p结点的颜色,然后p结点的颜色变为黑色
  2. LR型:对p结点的左孩子s结点(5)左旋
  3. 右旋结点p
  4. 双黑变单黑

image-20240627114945181

代码实现

在STL中,我们常分为 RL+RR、LR+LL两组,因为RR和LR后面的步骤都是一样的,RL和RR后面的步骤都是一样的

我们以RL+RR为例:

bool isRL = false;
// 兄弟结点右孩子是黑的,所以左孩子一定是红的
if(getColor(sibling->right) == Color::BLACK)
{	
    isRL = true;
    // RL变色规则
    if(isRL)
    {
        setColor(sibling->left, getColor(node->parent));
        setColor(node->parent, Color::BLACK);
    }
    // 兄弟结点右旋
    rightRotate(sibling);
    // 旋转后更正兄弟结点指向
    sibling = node->parent->right;
}
// RR类型
// RR变色规则,跟RL类型不同
if(!isRL)
{
    setColor(sibling->right, getColor(sibling));
    setColor(sibling, getColor(node->parent));
    setColor(node->parent, Color::BLACK);
}
// 左旋结点
leftRotate(node->parent);
node = root;

在上述代码中,我们使用一个布尔变量isRL判断是RR类型还是RL类型,这是因为二者的变色规则不一样

LL+LR:

bool isLR = false;
// 结点左孩子是黑的,所以右孩子一定是红的
if(getColor(sibling->left) == Color::BLACK)
{
    isLR = true;
    // LR类型变色规则
    if(isLR)
    {
        setColor(sibling->right, getColor(node->parent));
        setColor(node->parent, Color::BLACK);
    }

    // 兄弟结点左旋
    leftRotate(sibling);
    // 旋转后更正兄弟结点
    sibling = node->parent->left;
}
// LL类型
if(!isLR)
{
    setColor(sibling->left, getColor(sibling));
    setColor(sibling, getColor(node->parent));
    setColor(node->parent, Color::BLACK);
}
// 右旋结点
rightRotate(node->parent);
node = root;

兄弟孩子都是黑色

image-20240630213444699

image-20240630213512382

代码实现

// 兄弟变红
setColor(sibling, Color::RED);
// 双黑上移
node = node ->parent;
if(node->color == Color::RED)
{
    // 上移是红,变单黑
    node->color = Color::BLACK;
    // 结束循环
    node = root;
}

兄弟是红色

兄父变色,朝双黑方向旋转,保持双黑继续调整

如下图所示,我们要删除一个15,实际上是找15的右子树上,最小值(17),替换15,实际上,就是删除17

此时原来的17就变成了双黑结点,此时兄弟结点是红色(34)

则兄父变色:23变成红色,34变成黑色

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落叶随峰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值