如果要学红黑树,那么就必须知道二叉树,毕竟红黑树本身就是一个二叉搜索树。只不过红黑树比一般的二叉搜索树更加稳定,也就是更加平衡,但是有没有AVL树那么的稳定,这换来的是红黑树比AVL数有更好的插入和删除效率,但是查找效率并没有比AVL差很多。下文我将用RBT代替红黑树。
二叉搜索树的删除
介绍RBT的删除,就先要知道二叉搜索树的删除(知道的同学可以直接跳过)。
删除分为四步:
1.找到删除点假设为X
2.找到X的代替点D,这里代替点可以有两个:一个是X左子树的最大点,也就是X左子树的最右点(也就是前驱点);另外一种就是X的右子树的最小点,也就是X的右子树的最左变点(也就是后继点)。
3.将X的值改成为代替点D。
4.如果代替点有子节点,那么,删除代替点,并用其子节点接上这个缺口;如果无子节点,则直接删除。
这里我们要删除15,那么代替点可以为16(后继)或者14(前驱)。接着我们将15的值改为代替点的值,然后删除原代替点,并用其子节点补上。好了,二叉搜索树的删除就结束了,是不是特别简单?
PS:18和19画反了。
RBT的删除概述
先来看看RBT的定义:
(1)每个节点或者是黑色,或者是红色。
(2)根节点是黑色。
(3)每个叶子节点(NIL)是黑色。 [这里叶子节点,是指为空NIL的叶子节点!]
(4)如果一个节点是红色的,则它的子节点必须是黑色的。
(5)从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点。
比较重要的是4.5,BRT所做的操作很多都是为了满足4.5条属性。因此一定要记住!
RBT的删除分为两个步骤:
1.删除节点,也就是最简单的二叉搜索树的删除操作,只不过除了使用代替的值D替换被删除点的值X以外,还要保证原X点的颜色不变。
2.调整节点颜色,使得满足RBT的5个属性(主要是4,5)。
假设我们使用了后继的方法完第一步删除节点的操作。并且用D表示要删除的代替点,P表示D的Parent,S表示D的Sister,SL、SR表示LeftTree和RigthTree,DR表示D的DR。
RBT的删除Case讨论
Case1:D为红色,此时DR肯定是NIL。(别问为什么,去看性质4.5)
因为D为红色,那么删除以后不影响左边路径黑节点的个数,此时直接用DR补上。
图上的DR我写错了,哈哈,左右不分。
Case2-1:代替D为黑色,且DR不为空,则DR必为红色(别问为什么,去看性质4.5)。
直接使用DR去补缺口并且改变颜色即可。
为啥?
大哥,你D是黑色的如果删除了那么就少了一个黑点了,如果DR颜色不变成黑色你还想平衡?
Case2-2 代替D为黑色,且DR为空,也就是为NIL,是黑色的(为啥?看性质4,5)。
分析:如果删除了D,那么P的左边黑点必定少一个,但是左边没有能补得了。此时就需要借助D的兄妹节点S来帮忙了。
Case2-2-1:DR为空,也就是为NIL,是黑色的。
若:DR兄妹节S点为红色,那么P肯定是黑色。
PS:这种情况SL或SR肯定不为NIL,想想为什么?
答:P为黑色,D为黑色,DR为黑色,那么P左边路径黑点是3;S为红色,SL为黑色,此时SL如果为NIL那么P右路径的黑点只有2了,这就说明删除操作前此树就不是RBT了。
这种情况,左边要可以向右边借一个黑点S来补一补。
Case2-2-2:DR为空,也就是为NIL,是黑色的。若:兄妹节点为黑色, 那么P不能确定。并且SL和SR颜色也不能确定我们再此对SL和SR做 讨论。(如果SL或SR为黑色,那么就必定为NIL)
接下来就对S、P、SL、SR的不同颜色组合做讨论。
Case2-2-2-1:代DR为空,也就是为NIL,是黑色的。
若:
兄妹节点为黑色,若P不能确定。
SL为红色,SR任意。 SL的子节点都为NIL(为什么?看4,5)
为了给P的左路径增加一个黑点,那就只能从右边子树去借用一个了,那就借一个SL吧,反正他是红色的,就算借走了也没事,然后再把SL变成黑色就好了,就到了图1。哎哟坏了,你左边倒是多了一个黑点了,但是我右边也有可能多一个黑点啊(如果P是红色就没有多,但是我们不知道P的颜色)有可能还是不平衡啊。好吧此时SL变成原来P的颜色也就是白色,P变成黑色就好了,如图2.
Case2-2-2-2:DR为空,也就是为NIL,是黑色的。
若:
兄妹节点为黑色,若P不能确定。
SL为任意,SR红色。
为了给P的左路径增加一个黑点,那就只能从右边子树去借用一个了,SL又不知道颜色(如果是红色的就是上面这样的情况),只能借S了。左旋一次,就借来了S如图1,此时左边平衡。右边也平 。。。等等,如果P是黑色的话右边路径不久少了一个黑点了?这样也是不平衡的啊,我们要做的是不改变右边路径上黑色点的数量情况下,使左边路径黑点增加一个。好吧,将P和S颜色变一下总行了吧! 也就是图2.
Case2-2-2-3:DR为空,也就是为NIL,是黑色的。
若:
兄妹节点为黑色,P为红色。
SL为黑色,SR黑色。(只要S点的儿子为黑色,必定为NIL,看4,5性质)。
此时P为红色,S为黑色。那么我们有两种选择了:
一种将P改为黑色(为了增加左边黑点),将S改为红色(为了使得右边黑点保持不变)。达到平衡。
另外一种以S为支点左旋,此时左边多了一个黑点,右边不变。达到了平衡。
Ps:我看很多博主都只有第一种方法,难道第二种方法是错的?请教各位同学。
Case2-2-2-4:DR为空,也就是为NIL,是黑色的。
若:
兄妹节点为黑色,P为黑色。
SL为黑色,SR黑色。
这中情况比较简单,我们可以减少一个右边路径黑点,将S改为红色就可以,如右下图。
或者增加左边一个节点,将SL作为根节点,此时达到平衡。什么?你确定?没错啊,左边增加了一个黑点,右边黑点数量没有变。别忘记了,SL和SR如果是黑色的(别问为什么了,看XXX),那就一定是NIL,那么SL可以当节点??黑人问号。
所以答案只有一个,那就是右下图。
总结一下:
我们分析了使用了后继法来删除红黑树。
删除点为D,我们不知道他的颜色,但是肯定的是D的左儿子肯定为NIL(D是最小的,没有比D更小的了,所以为NIL)。D的右儿子DR也不一定,P也不一定。也就是我们能唯一确定的是D的左儿子为NIL
于是我们对D、DR、P、S、SL、SR做了颜色的讨论。
case1:D是红色,DR肯定为黑色,且为NIL(别问为什么了。。。。)
case2:D是黑色:
– case2-1:D是黑色,DR不为NIL,必为红色
– case2-2:D是黑色,DR为NIL,必为黑色
- case2-2-1: case2-2条件+S节点为红色
case2-2-2:case2-2条件+S节点为黑色
- case2-2-2-1:case2-2-2+P不能确定,SL为红色,SR任意
- case2-2-2-2:case2-2-2+P不能确定,SL为任意,SR红色
- case2-2-2-3:case2-2-2+P为红色,SL为黑色,SR黑色
- case2-2-2-4:case2-2-2+P为黑色,SL为黑色,SR黑色
所有情况都分析完了,红黑树的删除你会了吗?