红黑树删除

chowming 2010-07-01 06:35:13
感觉比AVL插入复杂很多,谁能用通俗的语言解释下,便于理解
...全文
97 点赞 收藏 5
写回复
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
fjwyshan 2010-07-03
友情up
回复
kindlucy 2010-07-03
今天刚看了算法导论上的红黑树,觉得算法导论上讲的还是蛮清楚的。

首先,一开始的删除操作与二叉查找树的类似,然后,如果删去的节点是红色的话,红黑树的性质并没有被破坏,但是如果删去的节点是黑色的话,红黑树的性质被破坏了,因此需要重新修改树的结构,使之满足红黑树的性质。假设节点删去后,该节点的儿子x替换了它原来的位置。

现在,假设x是其父节点的左儿子。因为删掉的是黑节点,那么有p[x]往左走遇到的黑节点数量要比p[x]往右走遇到的黑节点少一个。

如果x是红色的,那么简单的将x的颜色改为黑色即可。

如果x是黑色的,情况就复杂了。设w是x的兄弟节点,分四种情况进行讨论:
Case1:w是红色的,那么执行一些操作使x的兄弟节点变为黑色的,即将Case1转变为Case2,3或4.

Case2:w是黑色的,且w的左、右儿子都是黑色的,此时将w变为红色的。即,使p[x]往右走遇到的黑节点数量也少了一个,这样p[x]往左走、往右走遇到的黑节点数量就都相同了,但是也导致p[p[x]]往p[x]那条路上走遇到的黑节点数量少了一个,因此,还是需要修改进一步树的结构,使之满足红黑树的性质,将x指向p[x],循环下去即可。

Case3: w是黑色的,且w的左儿子是红色的、右儿子是黑色的,此时,执行一些操作,使w的右儿子变成红色的,即将Case3转换为Case4。

Case4: w是黑色的,且w的右儿子是红色的。此时,执行一些操作,使得变换后,往x那边走遇到的黑节点的数量增加一个,这样红黑树的性质也保持了。

上面说的“执行一些操作”,就是改变了一些节点的颜色,进行左旋啊右旋啊什么的,具体的可以看书,算法导论上的图还是很清晰的。

献上 算法导论 上的伪代码:


RB-DELETE(T,z)
if left[z]=NIL[T] or right[z]=NIL[T]
then y <- z
else y <- TREE-SUCCESSOR(z)
if left[y]!=NIL[T]
then x <- left[y]
else x <- right[y]
p[x] <- p[y]
if p[x]=NIL[T]
then root[T] <- x
else if y=left[p[y]]
then left[p[y]] <- x
else right[p[y]] <- x
if y!=z
then key[z] <- key[y]
if color[y]=BLACK
then RB-DELETE-FIXUP(T,x)
return y


RB-DELETE-FIXUP(T,z)
while x!=root[T] and color[x]=BLACK
do if x=left[p[x]]
then w <- right[p[x]]
if color[w]=RED
then color[w] <- BLACK
color[p[x]] <- RED
LEFT-ROTATE(T,p[x])
w <- right[p[x]]
if color[left[w]]=BLACK and color[right[w]]=BLACK
then color[w] <- RED
x <- p[x]
else
then if color[right[w]]=BLACK
then color[left[w]] <- BLACK
color[w] <- RED
RIGHT-ROTATE(T,w)
w <- right[p[x]]
color[w] <- color[p[x]]
color[p[x]] <- BLACK
color[right[w]] <- BLACK
LEFT-ROTATE(T,p[x])
x <- root[T]
else (same as then clause with “right” and “left” exchanged)
color[x] <- BLACK


回复
AAA20090987 2010-07-02
看来每个人都有自己的感觉啊

我反而觉得红黑树的删除比AVL树简单多了。
回复
budweiser 2010-07-01
理论上说 AVL 比 RBTree 的平衡度要高, 这样应该具有更好的 搜索 性能, 但是会导致更大的 维护 开销。
但通过统计学 得出的结论是, RETree通常会具有比较好的平衡度,而且插入 删除的文虎开销较 AVL 要小得多。 这应该是 RETree的一个有点吧。

AVL 是通过 左右子树 的高度差来维护的, 而 RBTree是通过保持 RBTree的性质(这个不用我来说了把)来维护的。虽然看起来很复杂, 但仔细看明白以后就豁然开朗了。
回复
djjlove_2008 2010-07-01
STL的MAP容器的底层结构就是这个东东。
回复
发动态
发帖子
数据结构与算法
创建于2007-08-27

3.2w+

社区成员

数据结构与算法相关内容讨论专区
申请成为版主
社区公告
暂无公告