前言:本文解决的问题
- 红黑树的插入和删除比较
- 红黑树的删除
#1 插入VS 删除
前一篇文章[《5分钟学会红黑树插入》]()中说到,红黑树的插入主要是违背了第三条性质(红色节点无红色孩子),因此主要考虑的叔叔节点的性质;而红黑树的删除则违背了第四条性质,改变子树黑色节点的高度(从根节点到nil节点黑色节点数目可能改变),因此删除操作主要参照的是要删除节点的兄弟节点(sibling).
#2 删除
2.1 符号设置
删除比较复杂,为了更好地了解,这里用用到了双黑色节点的标记——当一个黑色节点被删除,用来替代它的后继黑色子节点将被标记为双黑色。因此删除的主要任务就说把双黑色节点变为单黑色。
Deletion is fairly complex process. To understand deletion, notion of double black is used. When a black node is deleted and replaced by a black child, the child is marked as double black. The main task now becomes to convert this double black to single black.
为方便后续理解,假设要删除的节点为v,代替它的后继子节点为u,v的兄弟节点为s,s的孩子节点为r。
2.2删除的分类
2.21 执行标准的BST删除(Perform standard BST delete )
当对BST进行删除时,我们总是删除的是叶子节点或者仅有一个孩子的节点;因此在这里,我们也只需要考虑叶子节点或者有一个孩子的节点。
2.22 简单分类1: v或者u是红色的(不能同时)
![v or u is red]()
这种情况最简单,直接把用来替代v的u变成黑色。
### 2.23 复杂一点的: v和u都是黑色
![u and v are both black]()
首先把u变成双黑色,然后问题就转变为如何把双黑色变成但黑色,这里又以下几种情况:
- 1 如果兄弟节点s是黑色,而且兄弟节点的孩子至少有一个是红色
If sibling s is black and at least one of sibling’s children is red,
这里需要作的是旋转。假设兄弟节点的红色子节点为r。
LL
s is left child of its parent and r is left child of s or both children of s are red.
LR
s is left child of its parent and r is right child of s.
RL
s is right child of its parent and r is left child of s
RR
s is right child of its parent and r is right child of s or both children of s are red.
* **2 如果兄弟节点是黑色的,而且兄弟节点的孩子节点都是黑色的**
> If sibling is black and its both children are black
这里需要是做的重新着色,如果根节点是黑色的,根节点要变成双黑色。始终保持黑色节点的高度一致。
![both children are black ]()
* 3 **如果兄弟节点是红色的**
> If sibling is red
把兄弟节点s往上移动,并把s兄弟节点和其父节点重新着色——把s和s.parent颜色互换。该情况又分两者:
#### Left Case (s是父节点的左孩子)
旋转父节点s.parent
#### Right Case(s是父节点的右孩子)
旋转父节点s.parent
![s is red]()
# 3总结
由于删除会改变黑色节点的高度,删除比较复杂。时间复杂度仍为O(log n)。