一、红黑树的特性
一个红黑树的节点node有如下5个属性:
node(parent, left, right, color, key)
红黑树的5条特性,使其接近于一颗近似的“平衡”搜索树:
1、节点的颜色是红色或者黑色
2、根节点是黑色的
3、所有叶子节点是黑色的
4、一个红节点的两个子节点均为黑色
5、从树中任何一个节点到其所有后代叶节点的简单路径上,包含相同数目的黑色节点
二、算法伪代码
1、旋转
以X为支点的左旋操作LEFT-ROTATE(T,x),改变了x的右孩子、父节点,y的左孩子、父节点,以及y的左孩子的父节点,有可能改变父节点的左or右孩以及T.root,参照图示,比较容易写出左旋的伪代码。
LEFT-ROTATE(T,x)
y = RIGHT(x)
p = PARENT(x)
RIGHT(x) = LEFT(y)
if(LEFT(y) != T.nil)
PARENT(LEFT(y)) = x
PARENT(y) = p
if(p == T.nil)
T.root = y
else
if (x == LEFT(p))
LEFT(p) = y
else
RIGHT(p) = y
LEFT(y) = x
PARENT(x) = y
2、插入
RB-INSERT(T,z)将节点z插入到红黑树中。首先按照普通的二叉搜索树将节点z插入,并涂成红色。然后再调用一个辅助过程RB-INSERT-FIXUP(T,z)使其恢复红黑树的性质。
RB-INSERT(T,z)
y = T.nil
x = T.root
while(x != T.nil)
y = x
if (z.key < x.key)
x = x.left
else
x = x.right
z.parent = y
if (y == T.nil)
T.root = z
else if (z.key < y.key)
y.left = z
else
y.right = z
z.left = T.nil
z.right = T.nil
z.color = red
RB-INSERT-FIXUP(T,z)
3. 辅助插入过程RB-INSERT-FIXUP(T,z)
充分考量RB-INSERT过程破坏红黑树的性质后,可能出现的各种情况,借助旋转操作与重新涂色,恢复红黑树的性质。
RB-INSERT-FIXUP(T,z)
while z.p.color == RED
if p == z.p.p.left
y = p.p.right
//case 1
if y.color == RED
y.color = BLACK
z.p.color = BLACK
z.p.p.color = RED
z = z.p.p
//case 2
else if z == z.p.right
z = z.p
LEFT-ROTATE(T,z)
//case 3
else
z.p.color = BLACK
z.p.p.color = RED
RIGHT-ROTATE(T,z.p.p)
else the same as clause with "right" and "left" swap
//case 1
//case 2
//case 3
T.root.color = BLACK
4、辅助删除过程移植操作RB-TRANSPLANT(T,u,v), 使用v来顶替原来的u的位置。
RB-TRANSPLANT(T,u,v)
if u.p == T.nil
T.root = v
else if u == u.p.left
u.p.left = v
else u.p.right = v
v.p = u.p
5、删除操作RB-DELETE(T,z)删除节点z,如果z没有子节点或者只有一个子节点,则做一次简单的移植即可。两个子节点的情况较为复杂,关键点在于删除z后,用哪个节点来替代z的位置。考虑z的左子树都小于z,右子树都大于z,不难发现,应当用z的右子树的后继来替代z的位置。另外,将替代z的节点涂上与z相同的颜色,控制删除造成的影响,最后调用RB-DELETE-FIXUP完成修复。删除算法用y来跟踪替换z的节点,用x跟踪替换y的节点,因为y被重新着色,用y-orignal-color记录y的初始颜色。
RB-DELETE(T,z)
y = z
y-orignal-color = y.color
if z.left == T.nil
x = z.right
RB-TRANSPLANT(T, z, z.right)
else if z.right == T.nil
x = z.left
RB-TRANSPLANT(T, z, z.left)
else y = RB-MINIMUM(z.right)
y-orignal-color = y.color
x = y.right
if y.p == z
x.p = z
else RB-TRANSPLANT(T, y, y.right)
y.right = z.right
y.right.p = y
RB-TRANSPLANT(T, z, y)
y.left = z.left
y.left.p = y
y.color = z.color
if y-orignal-color == BLACK
RB-DELETE-FIXUP(T,x)
6、辅助删除过程RB-DELETE-FIXUP(T,x)修复删除操作对红黑树的破坏。考虑如果y的颜色为红色,那么删除与移动不会导致红黑树性质的破坏。否则可能导致包含y的所有简单路径上的黑节点个数少了1。因为x替代了y的位置,可以将x看成双重黑色来弥补。我们所要做的就是跟踪x的轨迹,待其变为红黑色时将其涂成黑色。
RB-DELETE-FIXUP(T,x)
while x != T.root and x.color == BLACK
if x = x.p.left
w = x.p.right
//case 1
if w.color == RED
w.color = BLACK
x.p.color = RED
LEFT-ROTATE(T, x.p)
w = x.p.right
//case 2
if w.right.color == BLACK and w.left.color == BLCAK
w.color = RED
x = x.p
//case 3
else if w.right.color == BLACK
w.left.color = BLACK
w.color = RED
RIGHT-ROTATE(T, w)
w = x.p.right
//case 4
else
w.color = x.p.color
x.p.color = BLACK
w.right.color = BLACK
LEFT-ROTATE(T, x.p)
x = T.root
else the same clause with right and left swap
...
x.color = BLACK
来源:https://blog.csdn.net/weixin_38006908/article/details/102509231