红黑树的旋转

红黑树旋转记忆

关键词: 红黑树 旋转 记忆

参考:

  1. 动画红黑树,旋转的艺术-知乎-ACM算法日常的文章
  2. 红黑树快速入门-04删除-知乎-谢某人

因为红黑树操作的时候要考虑的情况太多了,需要“有规律”地记住。

  • 插入
    • 一条线,且叔叔不是红色
    • 一条线,叔叔是红色
    • 折线:转换成直线
  • 删除:最复杂,经分析只需考虑黑色结点的删除,再经分析只需考虑兄弟结点
    • 兄弟是黑色,其子节点也是黑色
    • 兄弟是黑色,右子节点红色
    • 兄弟是黑色,其子节点做红右黑
    • 兄弟是红色

红黑树满足如下五条约束:

  1. 节点要么是红色要么是黑色
  2. 根节点必须是黑色
  3. 叶子节点挂两个空节点(逻辑上)是黑色
  4. 每个红色节点有两个黑色子节点,推导出一条路径上不能有两个连续的红色节点
  5. 每条路径上必须有相同数量的黑色节点R

插入

首先,因为约束5,默认插入的结点颜色是红色。

其次,我们要记住一个最基本的旋转,假设插入结点为r1,插入后情况如下:

black, red

 b0
/\
b r0
 /\
 b r1

黑、红、红都在一条直线上,并且,最下面红色的叔叔结点是黑色

中间的红色结点就可以变成父节点,然后颜色反转,相当于把一条线变成了一个分叉。

b0              r0             b
 \              / \           / \
  r0    --->   b0 r1  <--->   r  r
   \
   r1

第二种情况,插入后为一条线,但是很不幸,插入结点的叔叔为红色

假设插入的是r2,那么我们暂时不需要旋转,先反转颜色

  b0                  r0
 / \                 / \
r0  r1     --->     b0  b1
     \                   \
      r2                 r2

但是,这时父节点颜色又变为红色了,就要考虑旋转了。

第三种情况,插入后为折线,我们可以转换成一条直线,然后交给其他情况处理,感觉有点像状态机。

 b0           b0
/            /
r0    --->  r1 
  \         /
  r1       r0

删除

删除很难记全,不如直接去看知乎。

case1,兄弟是黑色,其子节点也是黑色,解决方法是

兄弟变红,向上递归解决

case2-case4:无法用语言描述,天知道怎么想出来的。

posted @ 2022-03-15 11:48  ticlab  阅读(76)  评论(0编辑  收藏  举报