红黑树旋转记忆
关键词: 红黑树 旋转 记忆
参考:
因为红黑树操作的时候要考虑的情况太多了,需要“有规律”地记住。
- 插入
- 一条线,且叔叔不是红色
- 一条线,叔叔是红色
- 折线:转换成直线
- 删除:最复杂,经分析只需考虑黑色结点的删除,再经分析只需考虑兄弟结点
- 兄弟是黑色,其子节点也是黑色
- 兄弟是黑色,右子节点红色
- 兄弟是黑色,其子节点做红右黑
- 兄弟是红色
红黑树满足如下五条约束:
- 节点要么是红色要么是黑色
- 根节点必须是黑色
- 叶子节点挂两个空节点(逻辑上)是黑色
- 每个红色节点有两个黑色子节点,推导出一条路径上不能有两个连续的红色节点
- 每条路径上必须有相同数量的黑色节点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:无法用语言描述,天知道怎么想出来的。