红黑树伪代码冗余

con*_*sed 13 algorithm red-black-tree clrs

在Algorithms Third Edition的介绍中,他们有一个红黑树删除的伪代码实现.这里是...

RB-DELETE(T, z)
    y = z
    y-original-color = y.color
    if z.left == T.nil
        x = z.right
        RB-TRANSPLANT(T, z, z.right)
    elseif z.right == T.nil
        x = z.left
        RB-TRANSPLANT(T, z, z.left)
    else
        y = TREE-MINIMUM(z.right)
        y-original-color = y.color
        x = y.right
        if y.p == z
                x.p = y       // <--------- why????
        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-original-color == BLACK
        RB-DELETE-FIXUP(T, x)
Run Code Online (Sandbox Code Playgroud)

TREE-MINIMUM只找到树中的最小值,RB-TRANSPLANT取第二个参数的父级,并指向第三个参数,第三个参数的父级是第二个参数的父级.

通过我的评论,他们测试yp是否为z,如果是,则将xp设置为y.但是x已经是y.right,所以这就像说y.right.p = y,但是y.right.p已经是y了!他们为什么要这样做?

这是他们的解释......

"但是当y的原始父级是z时,我们不希望xp指向y的原始父级,因为我们正在从树中删除该节点.因为节点y将向上移动以在树中取z的位置,所以在第13行中将xp设置为y会导致xp指向y的父节点的原始位置,即使x == T.nil.

所以他们希望让x的父母成为...它已经是...

Ant*_*ima 11

他们在文中指出x也可以是Nil,即当y.right为Nil时.似乎Nil在这个代码中也由一个节点表示,并且他们不想留下悬空指针.

  • 为了向其他人澄清,T.nil是表示树中所有叶节点的节点.没有它,你会有O(2 ^ h)零叶,这是浪费空间.T.nil的属性,左,右和父,是任意的.所以当x = y.right时,如果x = T.nil,则x的父级将不是y.如果最后一次调用RB-DELETE-FIXUP(T,x)要正常工作,则需要将其设置为y. (3认同)
  • 啊我明白了!灯泡。这就是他们说要利用 T.nil 节点具有左、右和父属性这一事实时的意思。谢谢! (2认同)