如果不知道红黑树的定义,以及新增,请看上一篇文章,《红黑树,新增》。
那删除呢?
删除,大体上分三种情况
1、删除没有子节点(null不算)的节点
2、删除一个子节点的节点
3、删除拥有两个子节点的节点。
而对于删除拥有两个子节点的节点(也就是情况3),通俗的做法,就是拿被删除节点的后继节点来接替它,这个后继节点必然是(没有子节点或者只有一个子节点)这样的一个节点。等价于删除了那个后继节点,也就是1 、2这两种情况。
(这个可能比较难理解,推荐画一下树比划一下,看看是是否是这样,这对理解删除拥有两个子节点的节点来说,至关重要。)
后继节点我们应该比较熟悉,就是树中序遍历情况下,被删除节点的下一个节点。
我们首先得有个概念,删除一个黑色的节点,可能是会导致不平衡的,到时候我们必须重新平衡。
所以我们具体来讨论1 、2两种情景
分被删除节点是红色还是黑色来讨论。
我们先来讨论,被删除的节点是红色的这种情况
下面这两种都是删除红色节点的情况。
因为如果删除黑色节点,可能会导致不平衡的发生,情况就有些复杂了,我们先从简单的来看。
1、删除没有子节点(null不算)的节点(红色)
因为是红色节点,不会影响平衡。删完了事,不需要重新平衡。
2、删除一个子节点的节点(红色)
如图所示,有一个节点的红色节点,不可能存在,所以我们不会遇到这种情况。
我们再来讨论,被删除的节点是黑色的这种情况
我们首先来建立一个位置印象。
因为从这里开始,我们将会分很多种情况来讨论,不要担心,我们会一个一个慢慢讲清楚的。但是这种节点的名称跟位置的关系,需要大家先记忆清楚,后续将不再标注。
B这边,代表的是一个被删除的黑色节点,重新保持自身平衡的情况。但是高度可能跟它的兄弟不一致,导致了P的不平衡。
我们具体情况具体分析,一个一个来。
被删除的节点有一个子节点(黑色)
这种情况,B已经保持了自身的平衡,而且高度也跟它的兄弟节点一样,保持了父亲节点的平衡,所以到此为止了。
被删除的节点没有子节点(黑色)
那么就会导致一个空节点,它自身的高度是平衡了,但是P节点两边的高度便不平衡了。
所以,我们必须对P进行调平,如果P调平了之后,GP无法保持平衡,那么就需要对GP进行调平,就这样一层一层递归上去。
我们现在的目标,就是对P进行调平。
那么P如何调平呢?
这跟P的颜色,S的情况都有关系,不能一概而论。
如果B为根节点,那么无需进行调平操作。
2兄弟是黑色节点
2.1兄弟节点没有子节点
这边高度,就不计算NULL(空)节点的高度了,虽然NULL节点也算一个黑色的节点(要占1个高度),图中也没有画出NULL节点来。思维图里说兄弟子节点全黑,指的是子节点全是空节点,这样才是全黑。
2.2兄弟节点有子节点
子节点也只能是红色的,1个或者2个红色的子节点。
上图在S、P之间的SR,以及SL会插在旋转后的P这边。
总结一下,如果兄弟节点是黑色的,并且没有子节点的话,就跟父亲节点的颜色有关。
父亲颜色是红色的可以进行平衡,父亲颜色如果是黑色的,那么只能往祖父节点那边寻求平衡了。
如果兄弟节点是有子节点的,那么一定是可以进行平衡的。
3兄弟是红色节点
下一步即将3.1里的P与SR,3.2里的P与SL交换颜色即可。
至此,如何在删除一个节点后保持平衡,终于讲完了。
非常推荐大家手动画一遍,走一遍这个流程。
最后,红黑树有什么用?
经过上面这一番插入、删除,左旋右旋平衡操作,大家应该有一种感觉。就是它似乎,并不是对所有的插入删除操作都进行重新平衡处理,特别是当操作对象是红色点的时候,这种钝感就尤为强烈。
可以感觉出来的是,它应该比平衡二叉树调整的次数要少一些。高度肯定还是平衡二叉树要矮一点。
工程上,大家似乎更喜欢用这个红黑树,而不是使用最快的平衡二叉树。
是平衡二叉树太敏感了么?
作用也是跟平衡二叉差不多,做排序,查询使用的。