【干货】几个口诀帮你记忆红黑树的操作实现

红黑树是一种常用的平衡二叉树数据结构,搜索(search)、插入(insertion)和删除(deletion)的时间复杂度为O(Logn)。

用于C++实现Map/Set, Java实现TreeMap/HashMap等数据结构,此外还可以用于实时计算程序和函数式编程中。

 【红黑树的性质】

  • 根节点总为黑色。Root of tree is always black
  • 不存在相邻的红色节点。There are no two adjacent red nodes
  • 从任何一个节点出发到它的任何一个NULL叶节点的所有路径,经过的黑色节点数量之和相同。Every path from a node (including root) to any of its descendant NULL node has the same number of black nodes

 Features

  • 每个红黑树的高度: h ≤ 2Log2(n+1)
  • 每个红黑树的黑色节点数: Nblack ≥ n / 2
  • The height of a Red-Black tree is always O(Logn) 
  • 任何一个节点到叶节点的黑色节点数(Black Height):  BH >= h/2.
  • There is a root to leaf path with at-most Log2(n+1) black nodes


 【红黑树的操作】

首先说明:我主要是总结操作实现的步骤,方便你更好的记忆,这里并没有放任何实现代码。

【插入操作】

  1. 进行平衡二叉树插入操作
  2. 修复插入节点可能出现的违规,根据插入节点的情况分类
    1. 插入节点没有根节点: 染黑插入节点
    2. 插入节点Parent为黑: 直接插入
    3. 插入节点Parent为红: 根据Uncle的情况分类
      1. Uncle是红色的: 染黑Uncle和Parent,染红GrandParent
      2. Uncle是黑色的:
        1. 三角型: 旋转Parent,执行直线型的操作
        2. 直线型: 旋转GrandParent,交换插入节点与GrandParent的颜色

【插入操作口诀】

我根我爸黑,那就很简单。
我爸要是红,伯伯也红,黑爸黑伯红祖父,伯伯若黑,三角转成直,直也转一次,转后祖父与兄色互换,全部结束根染黑。


【删除操作】

  1. 搜索删除节点

  2. 查找替换节点

  3. 删除节点是叶节点,替换节点为null

  4. 删除节点有一个子代,替换节点为该子代

  5. 删除节点有两个子代,替换节点为后继节点(successor)

  6. 执行删除节点,根据删除节点和替换节点的情况分类讨论

  7. 若删除节点有两个后代: 交换替换节点与删除节点键值,对替换节点进行删除操作

    1. 若删除节点无两个后代:
    2. 删除节点是树根: 直接删除或替换
    3. 删除节点是叶节点: 若删除节点是黑色,则为双黑,修复双黑
    4. 删除节点有一个后代: 若不是双黑情况,染黑替换节点

【删除操作口诀】

删除节点两后代,交换键值往下看。

删除节点是树根,直接删除或替换。

删除节点无后代,自己若黑修双黑。

删除节点有一子,若是红子染成黑。


【修复双黑操作】

什么是双黑和修复双黑?

双黑是指删除操作中替换节点与删除节点均为黑色的情况,双黑标记表明了当前树违背了黑色节点数目一致的原则,需要进行修复。修复双黑就是为了保证红黑树满足上述合法性的操作。

具体操作:

根据删除节点的兄弟节点情况进行分类讨论:

  1. 若不存在兄弟: 双黑要传递给父亲,对父亲进行修复双黑
  2. 兄弟是红色: 染红父亲,染黑兄弟,把兄弟转上去,转化为兄弟为黑的情况
  3. 兄弟是黑色,此时需要讨论兄弟儿子的情况
    1. 兄弟没有红色儿子,先染红兄弟,然后讨论父亲颜色的情况
      1. 父亲为红色: 染黑父亲即可
      2. 父亲为黑色: 对父亲节点修复双黑
    2. 兄弟有红色儿子,根据兄弟与兄弟儿子形成的结构进行分类讨论
      1. 直线型: 兄弟儿子染成黑色,兄弟染成父亲色,然后把兄弟转上去
      2. 三角型: 把兄弟儿子染成和父亲同色,把兄弟儿子转到兄弟的位置,再把兄弟的儿子转到父亲的位置


写在最后

我在该文章中没有去说明实现步骤的原因和细节,因为这篇文章主要是为了提供实现操作记忆的口诀和动图,和记忆代码相比,这样更能方便记住,可以在面试笔试的时候再进行展开。

我还制作了一个关于红黑树的视频,欢迎各位观看:

https://www.bilibili.com/video/av45909616/

关于本人:我是一名工作经验两年多的前端,主要方向是数据可视化和工具开发,最近离职重新学习各种计算机基础,由于经验不足,可能会有不少错误之处,如能够指正将十分感激。


转载于:https://juejin.im/post/5c86897ae51d45378301e359

你可能感兴趣的:(【干货】几个口诀帮你记忆红黑树的操作实现)