深入理解红黑树的演变、变色、旋转!从此告别背诵面试题!

想要了解红黑树,首先你得了解二叉查找树(二叉排序树),了解左旋、右旋,你才能看懂这篇文章。

推荐文章:二叉平衡树(AVL树)从演变、平衡、旋转加练习题逐步分析,看不会过来打我

红黑树的演变

在前一篇文章也讲过,AVL平衡树的演变,其实红黑树也一样,它也是基于二叉搜索树实现的,可能你会问,不是已经演变出AVL树了吗?为什么还要有红黑树?

原因是这样的,AVL树追求的是极致平衡,当你插入一个元素时,旋转的次数不能预估,当插入、删除特别频繁时,树就会不停地旋转,严重影响效率,这时候红黑树出现了,红黑树能保证树的大致平衡,最多旋转3次就能实现平衡,它的查找时间复杂度为O(logn)。

红黑树的特点

  • 所有的节点只能是黑色或红色
  • 根节点必须为黑色
  • 两个红色节点不能相连接
  • 所有叶子节点都是黑色
  • 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点

每次新插入的数据一定是红色,如果插入的数据一旦是黑色,那么树就失去平衡了,因为整个树的节点都是黑色的,满足红黑树的所有特点,也就没有变色或旋转可言,所以每次新插入的数据一定是红色的,当打破红黑树的规则时,就会发生变色或旋转。

颜色变换和旋转的规则

1. 当前节点(红色)的父节点是红色且当前节点的叔叔节点也是红色
  1. 把父节点设置为黑色
  2. 把叔叔节点也设置为黑色
  3. 把爷爷节点设置为红色
2. 当前节点的父节点是红色,叔叔节点不存在或叔叔节点为黑色,且父节点是爷爷节点的左子节点
2.1 LL(/)型,也就是当前节点与父节点都处于左子节点

当前节点13为左子节点,父节点14为左子节点,这种情况先变色再旋转

  • 第一步,变色,父节点变为黑色,爷爷节点变为红色

  • 第二步,右旋(由/型变为^型)

2.2 LR(<型),当前节点为父节点的右子树,父节点为爷爷节点的左子树

  • 先变为LL,父节点14左旋

  • 根据LL的规则,变色,旋转

3. 当前节点的父节点是红色,叔叔节点不存在或叔叔节点为黑色,且父节点是爷爷节点的右子节点
3.1 RR(\)型,也就是当前节点与父节点都处于右子节点

  • 变颜色,父节点变为黑色,爷爷节点变为红色

  • 爷爷节点为当前节点,左旋

3.2 RL(>)型,当前节点在父节点的左子树,父节点在爷爷节点的右子树

  • 先变为RR,右旋

  • 根据RR,变色,左旋

举例

  • 例1

    当前节点0038的父节点是红色且当前节点的叔叔节点0041也是红色,满足变颜色的条件:

    1. 把父节点设置为黑色
    2. 把叔叔节点也设置为黑色
    3. 把爷爷节点变为红色

  • 例2

    当前节点45,它的父节点40是红色,但是它的叔叔节点80是黑色,并且当前节点是LR,先变为LL,再变色旋转。

    上面这张图节点40和节点45相连,且都是红色,根据红黑树的规则需要变色或旋转,节点40的父节点45是红色,它的叔叔节点80是黑色,且当前节点为LL,变色并右旋。

    1. 当前节点的父节点变为黑色

    2. 爷爷节点变为红色

    3. 爷爷节点以父节点为轴,右旋

总结

遇到不满足红黑树条件的时候,首先判断当前节点的父节点和叔叔节点是否都为红色,如果都为红色,直接变色(父节点和叔叔节点变为黑色,爷爷节点变为红色),然后以爷爷节点为当前节点继续判断。如果当前节点没有叔叔节点或叔叔节点为黑色,那么判断当前节点是LL、LR、RR、RL,如果是LL或RR,则直接变色(父亲节点变为黑色,爷爷节点变为红色)并右旋或左旋。如果是LR或RL,则先把它们通过右旋或左旋变换为LL或RR,再进行变色旋转操作。

练习

依次插入12,14,15,16,17,18,19,20,1,11,画出最终红黑树。

  1. 插入12

  2. 再插入14

  3. 再插入15

    判断当前节点的叔叔节点是否为红色,叔叔节点不是红色,则判断该树为RR,需要变色并左旋

  4. 再插入16

    不满足红黑树规则,先判断父亲节点和叔叔节点是否都为红色,都为红色,变色(父亲节点和叔叔节点都变为黑色,爷爷节点变为红色,根节点除外)

  5. 再插入17

    RR,先变色再左旋

  6. 再插入18

  7. 再插入19

  8. 再插入20

    变色后发现依然不满足红黑树规则,判断当前节点18父节点16是红色,叔叔节点12为黑色,这时候不需要变色操作,再看当前树为RR,所以需要先变色再左旋

  9. 再插入1

  10. 再插入11

完整流程如下图:

  • 12
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

YoungJ5788

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

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

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

打赏作者

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

抵扣说明:

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

余额充值