前言:本文解决的问题

  • 红黑树的插入和删除比较
  • 红黑树的删除


#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

删除黑色节点操作红黑树python实现 红黑树删除元素_红黑树

RR

s is right child of its parent and r is right child of s or both children of s are red.

删除黑色节点操作红黑树python实现 红黑树删除元素_父节点_02


* **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)。