红黑树
旋转
LEFT_ROTATE(T,x)
y = x.right
x.right = y.left
if y.left != T.nil
y.left.p= x
y.p = x.p
if x.p == T.nil
T.root = y
else if x == x.p.left
x.p.left = y
else x.p.right = y
y.left = x
x.p = y
插入
RB_INSERT(T,z)
y = T.til
x = T.root
while x != T.til
y = x
if z.key < x.key
x = x.left
else x = x.right
z.p = 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
RB_INSERT_FIXUP(T, x)
RB_INSERT_FIXUP(T,x)
while z.p.color == RED
if z.p == z.p.p.left
y = z.p.p.right
if y.color == RED
z.p.color = BLACK
z.p.p.color = RED
y.color = BLACK
else if z == z.p.right
z = z.p
LEFT_ROTATE(T,z)
esle
z.p.color = BLACK
z.p.p.color = RED
RIGHT_ROTATE(T,z)
else (same as then clause with right and left exchanged)
T.root.color = BLACK
情况1, z的叔节点y是红色的
情况2, z的叔节点y是黑色的,且z是一个右孩子节点
情况3, z的叔节点y是黑色的,且z是一个左孩子节点
情况2让z指向红色的z.p ,左旋到情况3, 在情况2和情况3 颜色不改变。 把z.p改成黑色。
删除
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
一颗二叉搜索树T中删除一个节点z的整个策略有三种基本情况
1,z没有孩子,那么简单删除它,并修改它的父节点,用Nil作为孩子来替换它
2,z只有一个孩子,那么将孩子提升为z的位置,并修改z的父节点,用z的孩子来替换z
3, 如果z有两个孩子,那么找z的后继y(一定是z的右子树中),并让y占据树中z的位置,z原来右子树部分成为y的新右子树,并且z的左子树成为y的新左子树
TREE_DELETE(T,z)
if z.left == NIL
TRANSPLANT(T, z, z.right)
else if z.right == NIL
TRANSPLANT(T, z, z.left)
else y = TREE_MINIMUM(z.right)
if y.p != z
TRANSPLANT(T, y, y.right)
y.right = z.right
y.right.p = y
TRANSPLANT(T, z, y)
y.left = z.left
y.left.p = y
TREE_MINIMUM(x)
while x.left != NIL
x = x.left
return x
RB_DELETE(T, z)
y = z
y.originalcolor = 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 = TREE_MINIMUM(z.right)
y.originalcolor = y.color
x = y.right
if y.p == z
x.p = y
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.originalcolor == Black
RB_DELETE_FIXUP(T, x)
如果Y 是黑色的,则会产生三个问题,可以通过RB_DELETE_FIXUP进行补救。
第一,如果y是原来的根结点。而y的一个红色的孩子成为新的根结点,这就违反了性质2
第二,如果x,和 x.p是红色的,则违反了性质4
第三,在树中移动y导致先前包含y的任何简单路径上黑结点个数少1,因此y的任何祖先不满足性质5
情况1, x的兄弟节点w是红色,因为 w必须是黑颜色,所有改变w和 x.p的颜色。然后对x.p进行一次左旋。 就会将情况1,转换为2,3,4处理。这些情况由W的子节点的颜色来区分。
情况2,x的兄弟节点为黑色,而且w的两个子节点都是黑色。因为w也是黑色的,所以从x和w上去掉一重黑色,使得x只有一重黑色,而w为红色。为了补偿从x和w去掉的一重黑色,在原来是红色或黑色的x.p
上新增一重额外的黑色。通过将x.p作为新的节点x来重复while循环。注意到,如果通过情况1 进入到情况2,则新节点x是红黑的,因为原来的x.p是红色的。因此新的节点x.color属性值c为红色。
情况3, x的兄弟节点w是黑色的,w的左孩子是红色的,右孩子是黑色的。交换w和左孩子的颜色,然后对w进行一次右旋。
情况4, x的兄弟节点w是黑色的,且w的右孩子是红色的。通过进行某些颜色修改,并对x.p进行一次左旋,可以去掉x的额外黑色,从而使他变成为单重黑色。