zoukankan      html  css  js  c++  java
  • 数据结构之红黑树

    Red-Black Tree | Set 1 (介绍)

     红黑树是一种平衡二叉树,其每个结点满足以下条件:

    1. 每个结点都有颜色(黑或);
    2. 根结点总是黑色;
    3. 不存在两个相邻的红色结点(一个红色结点不能有红色的父结点或者红色子女结点);
    4. 从根到空节点的每条路径都有相同数量的黑色节点。

       

    为什么选择红黑树?

      大部分BST操作(e.g. 搜索,最大,最小,插入,删除…等)的时间复杂度为O(h),h为树的高度。对于一颗歪斜的BST而言,其时间复杂度可能会变成O(n) 。如果我们想确保每次插入和删除后树的高度总保持在Log(n),及时间复杂度为O(h),则我们需要采用红黑树。红黑树的高度总是保持在Log(n),n是树的结点数。

     红黑树 VS AVL 树

      AVL树相对于红黑树而言更加的平衡,但在插入和删除过程中会涉及很多旋转操作。因此当你的应用需要频繁插入和删除的时候,红黑树或许是更好的选择;当你的应用不需要频繁的插入和删除,但需要频繁进行查询操作时,AVL树相比红黑树或许会更好。

    红黑树是如何保持平衡的?

      

     红黑树的黑色高度       

      黑色高度是从节点到叶子的路径上的黑节点数。叶节点也被计算为黑色节点。从上面的属性3和4,我们可以得出,高度h的节点有黑色高度> =h/2 。

    每一个有n个节点的红黑树具有高度≤log2(n + 1)             

    这可以用下面的事实来证明:             

      1)对于一般的Binary Tree,令k为所有根到空结点路径上的最小节点数,n = 2^k-1(Ex. 如果 k为3,n为至少7)。这种表达也可以写为k≤log2(n + 1)             

      2)从红黑树和上述4属性,我们可以说在红黑树有n个节点,根到叶的路径最多有log2(n + 1)个黑色结点。             

      3)从红黑树的3属性,我们得出,在红黑树中黑色结点的数目至少为⌊n / 2⌋,n是节点总数。             

    从以上3点,我们可以得出结论,事实上,有n个节点的红黑树具有高度h≤log2(n + 1)

    Red-Black Tree | Set 2 (Insert)

      对于AVL树而言,当进行插入操作后,我们通过旋转(Rotation)来实现树的再平衡。而在红黑树中,我们将通过以下两种操作来实现平衡:

      1)Recoloring

      2)Rotation

      我们会尝试重新染色,当重新染色色不起作用时,则会进行旋转操作。

    红黑树的插入

    • 调用BST的插入算法,并为新元素结点染色;
    • 若插入之前为空树,新结点作为根结点插入,染成黑色;
    • 若插入前树非空,
      • 把新结点染成红色;
      • 若父结点是黑色,则算法结束;
      • 否则,进行 “双红调整” 。

      

    双红调整的情况

      【叔父结点】指一个结点的父结点的兄弟结点

    • 情况 1:叔父结点是红色:XYr
      • 需要换色
      • 换色后继续检查平衡!
    • 情况 2:叔父结点是黑色:XYb
      • 需要旋转或重构
      • 每个结点的黑高度不变,调整完成

       

    针对XYr的调整:换色

    • 四种情况:LLr、RRr、LRr、RLr
    • 以LLr为例:父祖换色

      

    针对XYb的调整:旋转

    • 四种情况:LLR、RRb、LRb、RLb

       

    换色调整实例

    • 插入4:首先调用BST的插入算法

      

    • 续 1

      

    • 续 2

      

     Red-Black Tree | Set 2 (Delete)

    红黑树结点的删除

    • 先调用BST的删除算法
      • 如果被删除的结点有一个或两个外部结点,则直接删除;
      • 如果被删除的结点没有外部结点,则在右子树中寻找最小值结点(或在左子树中寻找最大结点),于该结点进行值交换(颜色不变);
      • 此时最小值结点(或最大值结点)成为被删结点,转换为被删结点有一个或两个外部结点的情况。
    • 待删除结点有两个外部结点
      • 直接把该结点变为外部结点
      • 若该结点是红色,则算法结束
      • 若该结点是黑色,删除后红黑树不平衡!“双黑” 
    • 待删除结点只有一个外部结点
      • 如果该结点是黑色,其非空子女结点为红色
      • 将其子女结点提升到该结点位置后,颜色变黑

       

     双黑结点的调整

    • 结点删除后,问题是:
      • 解决 “双黑” 结点现象
    • 讨论前提:双黑结点是待删除结点的左子女结点(右子女结点对称处理即可)
    • 有三种情况:
      • 双黑结点的兄弟结点是黑色,且兄弟结点的子女结点有红色
      • 双黑结点的兄弟结点是黑色,且兄弟结点有两个黑色子女结点
      • 双黑结点的兄弟结点是红色

    双黑结点调整:情况 1

    • 双黑结点与其红色侄子 “八字形外撇”
    • 解决方法:单旋转
      • 将兄弟结点C提上去
      • C继承原来父结点B的颜色
      • 把B染成黑色,D染黑色,其他颜色不变

     

    双黑结点调整:情况 1-2

    • 双黑结点与其红色侄子 “同边顺
    • 解决方法:双旋转 
      • 先右单旋,将D结点旋转为C结点的父结点
      • 再左d单旋,将D提上去作为根结点,继承原理子根B的颜色,B染成黑色

      

    双黑结点调整:情况 2

    • 双黑结点的兄弟结点是黑色,且有两个黑色子女结点
    • 解决方法:父祖换色、继续检查
      • 把C染成红色,B染成黑色
      • 若B原为红色,则算法结束
      • 否则,对B继续作 “双黑” 调整

      B原为红色:黑--黑  =》 黑--红

      B原为黑色:红-黑-黑  =》 红--红

      

    双黑结点调整:情况 3

    • 双黑结点的兄弟结点是红色
    • 解决方法:单旋转转换为情况1或情况2

      

    结点删除示例

      

      

      

     

      

    红黑树插入、删除总结

    •  为了恢复红黑树的平衡,需要自底向根进行调整
    • 红黑树的结点插入
      • 换色
      • 旋转或重构:双红调整
    • 红黑树的结点删除
      • 重着色
      • 旋转或重构
      • 双黑结点调整
    • 其平均和最差时间复杂度为 O(log2n)
  • 相关阅读:
    VB程序破解常用函数
    去VB程序NAG窗口方法-4C法
    error LNK2005: _DllMain@12 已经在 XXXX.obj 中定义
    汇编中的test和cmp指令
    OD保存修改后的数据到EXE
    C++ 异常捕获 try 和 __try的区别
    CListCtrl选中行
    WindowsAPI解析IAT地址
    Usaco 4.3.1 Buy Low, Buy Lower 逢低吸纳详细解题报告
    全国青少年信息学奥林匹克分区联赛(N)竞赛大纲
  • 原文地址:https://www.cnblogs.com/ktao/p/7804441.html
Copyright © 2011-2022 走看看