• 8分钟,复习一遍红黑树


    简单介绍

    什么是红黑树?

    红黑树(Red Black Tree)是一种平衡二叉搜索树。红黑树是一种特化的AVL树(平衡二叉树),都是在进行插入和删除操作时通过特定操作保持二叉查找树的平衡,从而获得较高的查找性能。

    关于AVL树可以查看我的博客:juejin.cn/post/713638…

    为什么使用红黑树?

    红黑树相比AVL树,在检索的时候效率其实差不多,都是通过平衡来二分查找。但对于插入删除等操作效率提高很多。

    其次红黑树不像AVL树一样追求绝对的平衡,他允许局部很少的不完全平衡,这样对于效率影响不大,但省去了很多没有必要的调平衡操作,AVL树调平衡有时候代价较大,所以效率不如红黑树。红黑树只是做到了近似平衡,并不严格的平衡,所以在维护的成本上,要比AVL树要低。

    红黑树的高度只比高度平衡的AVL树的高度(log2n)仅仅大了一倍,在性能上却好很多。

    红黑树的插入、删除、查找各种操作性能都比较稳定。对于工程应用来说,要面对各种异常情况,为了支撑这种工业级的应用,我们更倾向于这种性能稳定的平衡二叉查找树。

    红黑树的前身 234树(4阶B树)

    它的效率不如红黑树

    234树:是一种多叉树,它的每个节点最多有3个数据项和四个子节点。

    节点分为3类:

    • 2节点:存储1个数据项,2个子节点

     3节点:存储2个数据项,3个子节点

     

    - 4节点:存储3个数据项,4个子节点 

    插入操作

    我们将1~10依次插入到234树中,观察如何平衡调整。

    首先是1~3的插入,插完以后已经变成一个4节点了。

     

    接着我们插入4,但是234树最多就是4节点,不能直接接在后面了。我们需要进行一步节点上溢操作。上溢中间的节点2,形成一个新的二节点,然后4就接在3后面。接着插入5就直接接在4后面形成4节点了。

     

    接着插入6,由于不能超过4节点又要进行节点上溢了,这里4上溢,然后形成的新树和2要进行合并。

     

    同理插入到8的时候也一样。

     

    最后插入10的时候,将8进行上溢。

     

    上溢并合并以后发现一久大于4节点,于是再将4进行上溢。

     

    最终我们的234树为

     

    234树与红黑树的关联

    左边是一棵红黑树,我们将红色节点上移到和他们的父节点同一高度上,实际上就是一棵234树。

     

    所以红黑树和234树是具有等价性的

    红黑树的黑色节点个数=234树的节点数

    234树的每一个节点中:

    黑色节点必为父节点,红色节点为子节点(黑色中间,红色两边)

    那么红黑树的每一种插入情况我们都可以转换为234树来理解。

    23树

    根据234树的逻辑我们可以完美套用到23树上,只需要知道234树最大是4节点,23树最大是3节点就行了。

    红黑树的性质

    红黑树是每个结点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉搜索树的基础上,对于任何有效的红黑树有如下性质:

    • 性质1. 结点是红色或黑色。
    • 性质2. 根结点是黑色。
    • 性质3. 所有叶子都是黑色,且都为空。
    • 性质4. 每个红色结点的父节点 and 子结点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色结点)
    • 性质5. 从任一结点到其每个叶子的所有路径都包含相同数目的黑色结点

    234树思维理解红黑树的操作

    下面我们采用234树来辅助理解红黑树的插入操作和删除操作。

    红黑树的插入操作

    如果插入的是根节点,则为黑色。

    其余情况插入的节点最开始一定为红色。(如果插入红色节点,仅有一种冲突状况,就是可能出现连续两个红色节点,这时候只需要旋转和变色进行调整。)

    红黑树的插入操作分为12种情况:

    • 插入节点的父节点为黑色(4种):直接插入,不做调整。因为不会影响到它红黑树的性质。

    叔父节点不是红色(4种):变色+旋转。

     

    对于(6)RR型 以234树的思维进行构想,我们会把13加在12的后面,但是红黑树不能有两个一样的红节点,所以我们需要进行变色,将中间的12变成黑色,两边的节点变成红色。

     

    光变色还是不行的,因为黑色节点必须是父节点。我们得进行一次左旋操作。

     

    对于(7)LL型 同理上面的RR型,直接染色加右旋即可。 对于(5)RL型 我们实际上希望11是在10和12中间的,这样的话一次旋转操作是不够的,需要做两次旋转

     

    首先插入节点染成黑色,然后插入节点的祖父节点也就是10染成红色。

     

    染色到此为止,接下来是旋转操作 首先是父节点12进行一次右旋

     

    然后祖父节点10进行一次左旋。最终到了下图所示的状态,这个是满足红黑树的性质的。

     

    • 对于(8)LR型 和上面的RL型同理,染色然后对父节点进行一次左旋,然后对祖父节点进行一次右旋。

    • 叔父节点是红色(4种上溢):变色。

    我们依旧用234树的思维来理解,这里无论是哪种情况都是肯定需要上溢的(将4抬高)

     

    然后开始染色,将插入节点的父节点和叔父节点染成黑色。上溢节点4作为新节点染成红色插入到上面一层。

     

    接着由于上溢节点在逻辑上是新插入到上一层的,于是依旧需要再用上面的方式再处理一次4这个节点。从整体上来看就是一种递归的形式。

    其他的情况实际上都是一样的,首先将父节点和叔父节点染黑,将祖父节点染红,祖父作为新插入节点上溢,然后递归处理。(写代码的时候需要将4种情况写明,毕竟位置不同。)

    红黑树的删除操作

    什么是下溢

    讲删除之前首先还是讲下溢,上溢情况我们知道是超过了4节点了需要把中间节点抬高。下溢则是原来是一个2||3||4节点,但是删除掉下面一层的节点后子节点数目和2||3||4节点需要的数目对不上了。

    讲完下溢之后我们开始正式讲删除操作<

  • 相关阅读:
    JavaScript中Object.prototype.toString.call()、instanceOf和Array.isArray()的区别
    【mmWave】二、IWR6843ISK-ODS毫米波雷达【固件开发】流程
    Vue学习之页面上中下三层布局
    Nginx 在 Linux 系统上安装 - 细节狂魔
    Java实战:Spring Boot项目Jar包加密
    Windows家庭版开启远程桌面的方法
    【毕业设计】29-交流电机步_进电机的转速测量与控制系统设计(原理图、仿真、源代码、答辩论文、答辩PPT)
    Java面试
    论文阅读——BERT
    手撕 视觉slam14讲 ch7 / pose_estimation_3d2d.cpp (1)
  • 原文地址:https://blog.csdn.net/m0_67322837/article/details/126587160