文章目录
简介
https://blog.csdn.net/weixin_43868793/article/details/123114745
删除
红黑树结点的删除可以分为两步
- 找到最终决定要移除的结点
- 通过红黑树的基本操作(左旋,右旋,变色)来保持红黑树性质
一、找到最终决定要移除的结点
先通过find
方法找到目标结点,大概有两种情况
1 无子
例如整个树只有一个根结点
:12
,最终决定要移除的结点
即为12
2 有子
只需向下寻找替代结点
,用替代结点的值
覆盖欲删除的结点
,然后这个替代结点
成为新的欲删除的结点
,继续判断。
2.1 删除有独子的结点
例如上图,删除14
,可以找到替代结点15
,15
覆盖14
,而15红
结点无子得
2.2 删除有多子的结点
例如上图,删除10黑结点
,那么需要在左子树中找到最大结点,右子树中找到最小结点,然后从中得到一个比较小的那个结点,作为替代结点
,
为什么要怎么做呢?
红黑树有保序的
,对上图这个树从根开始对树做中序遍历,会得到序列7,10,11,12,14,15
,是有序的,
如果不那样做,不能做到保序。
二、恢复红黑树性质
找到了最终决定要移除的结点
后,这个结点必定是一个叶子结点,直接删除可能会影响红黑树性质,需要根据一系列情况,做一些操作来恢复其性质。
大体分两种情况
1 红
最终决定要移除的结点
删除后不会影响红黑树的性质!
2 黑
2.1 红色兄弟
如图
现在欲删除43
左边删除掉43黑之后
,左子树黑高 -1
,显然以父为支,作左旋可以弥补缺失的黑高!,得到
可以发现,左边黑高多出一个,而且60
是根的时候,不应该是红色的,所以必需观察兄弟结点的左子的情况!再决定。
2.1.1 红色的兄弟有左子
根据红黑树性质,红色结点的父必是黑色,红色结点的子必是黑色!,
所以可以做一次双旋
!,以兄弟为支,作右旋,再以父为支,作左旋得到
恢复红黑树性质
2.1.2 红色的兄弟无左子
在删除的过程会出现,但红黑树本身并不会出现这种情况
2.2 黑色兄弟
一个结点是黑色的,其父可黑可红,其两个子结点可黑可红
但调整红黑树,只城要考虑父结点,和靠近自己的一个侄子
即可
即有
黑色兄弟,黑父,黑侄- 黑色兄弟,红父,红侄
黑色兄弟,红父,黑侄- 黑色兄弟,黑父,红侄
2.2.1 黑色兄弟,黑父,黑侄
不会出现这种情况,不满足红黑树性质
2.2.2 黑色兄弟,红父,红侄
如图
现在欲删除结点57
,显然双旋
操作可以实现恢复红黑树性质
对其父60红
作左双旋
得
再将60
变色得
但如果考虑下面这种没有左侄
情况,直接以父为支左旋即可
欲删除结点57
2.2.3 黑色兄弟,红父,黑侄
2.2.4 黑色兄弟,黑父,红侄
如下图欲删除结点25
以50为支作左双旋得
然后60红
变色得
如果是下面这种没有左侄
的情况,
父变色,以父为支直接左旋即可得
三、重新总结下如何恢复红黑树性质
约定:
欲删除结点为目标结点
直接删除
目标结点是红色的情况,直接删除即可
父置红,以父为支作单旋
目标结点是黑色,目标结点是左子,兄弟结点没有左子
目标结点是黑色,目标结点是右子,兄弟结点没有右子
侄置黑,以父为支作双旋
目标结点是黑色,目标结点是左子,兄弟结点有左子
目标结点是黑色,目标结点是右子,兄弟结点有右子