#红黑树知识点小结
文章目录
## 参考资料
##使用符号和术语:
N:当前操作的结点
P:当前结点N的父结点
U:当前结点N的叔结点
G:当前结点N的祖父结点,即父结点的父结点
left:当前结点是父结点的左孩子
right:当前结点是父结点的右孩子
A<-B:将B赋值到A
修复(restructure/rebalance): 指通过旋转和结点变色,使插入或删除结点后的红黑树重新满足基本的5个约束,修复算法只与位置和颜色相关而与结点键值大小无关
##平衡树的旋转
###左旋
旋转链的变化形似: \ -> /
###右旋
旋转链的变化形似: / -> \
##红黑树基本约束5点
- 结点
非红即黑
- 根结点必为
黑色
- 叶结点NIL必为
黑色
红色
结点的子结点必为黑色
(黑色
结点的子节点可红可黑
)- 任一结点到其所在分支的各叶结点,每条路径上的
黑色
结点数目相等
##红黑树插入
注:该插入算法参考@v_JULY_v的博客,相对wiki较为简洁
###概要和约束
- 基本插入同AVL树相似,AVL树的修复操作是旋转,但红黑树需要旋转配合变色
- 新插入的结点必为
红色
- 插入的结点作为根结点时,直接变为
黑色
- 插入结点作为在
黑色
结点的子结点
时,无须额外的修复操作
###插入修复
####情况:
- N的P是
红色
,U是红色
- N的P是
红色
,U是黑色
,P和N不同是right
或不同是left
- N的P是
红色
,U是黑色
,P和N同是right
或同是left
####插入修复算法要点:
-
对 1: P变
黑色
,U变黑色
,G变红色
,N<-G,再次判断情况进行修复 -
对 2:若P是
left
,则以N和P为链,左旋
,旋转后,N <- N的left
(即原本的P),进入情况3;
若P是right
,则以N和P为链,右旋
,旋转后,N <- N的right
(即原本的P),进入情况3 -
对 3:P变
黑色
,G变红色
,以P和G为链,若P是left
则右旋
,否则左旋
####图示
注:N为left
和N为right
的情况均已画出
##红黑树删除
注:该删除算法参考@Wikipedia,因为觉得v_July_v写的有点模糊
###概要和约束
1.删除修复时新增的符号:
D:最初需要被删除的结点
M:替换用的结点(是D的左子最右结点
或右子最左结点
)
C:M的子节点,若M无子节点,C为任意一个叶子子节点;若M有1个子节点,则C为该非叶子的子节点
2.在AVL数中,删除分三种情况,记被删除的结点为 D 的话:
-
- D无子节点;
-
- D有1个子节点;
-
- D有2个子节点;
分别对应三种重新平衡操作:
- 1)用NULL替换;
- 2)用其唯一的子节点直接替换;
- 3)用D左子的最右结点替换
在红黑树中,有子节点特指有非叶子结点,即非空节点
3.出于效率考虑1,第3种情况时,实际上并没有删除D,而是用D左子的最右结点的数据覆盖D的数据,真正被删除的是D左子的最右结点(不会有右子),这样就简化成一个删除无子节点或只有1个子节点的问题2
删除操作的实质:M的数据覆盖D的数据,删除M,M的位置由C补上,因此D的颜色没有改变
###删除修复
注:阅读以下内容前务必阅读 #概要
####情况:
将C标记为N,以下均以N为left
讨论
-
M是
红色
,直接用N补上,结束删除操作 -
M是
黑色
,用N补上后,分以下6种情况:
- N是
红色
- N是
黑色
且是根节点 - N是
黑色
,S是红色
,P是黑色
, - N是
黑色
,S是黑色
,S两子节点均为黑色
- N是
黑色
,S是黑色
,S右子是黑色
,左子是红色
- N是
黑色
,S是黑色
,S右子是红色
,左子颜色任意
####删除修复算法要点:
- 对1:把N染成
黑色
,直接结束 - 对2:直接结束
- 对3:P变
红色
,S变黑色
,把问题转化为S是黑色
的情况,重新进入算法 - 对4:S变
红色
, P变黑色
,重新进入算法 - 对5:S变
红色
,S左子变黑色
,以S和S左子为链,右旋
,重新进入算法 - 对6:令S的颜色变为P的颜色,P变
黑色
,S右子变黑色
,以P和S为链,左旋
,算法结束
####图示
注:下图只画出了N为`left`的情况,N为`right`的情况参见wiki的代码
##补充
- 叶结点为NIL,不含数据,仅标记结束
- 红黑树并不完全平衡,其确保没有一条路径会比其他路径长出俩倍,因而是接近平衡的
/*
author: lyuavery
date: 07-22-1016
*/
“Because merely copying a value does not violate any red–black properties, this reduces to the problem of deleting a node with at most one non-leaf child.”
– -- wikipedia ↩︎“Once we have solved that problem, the solution applies equally to the case where the node we originally want to delete
has at most one non-leaf child
as to the case just considered where it has two non-leaf children.”
– -- wikipedia ↩︎