CLRS 13.4删除

13.4-1
首先,情况 1 会转变为情况 2、3、4,所以接下来讨论情况 2、3、4。
情况 2 中,如新的 x 结点变成根,则退出循环然后将根结点着成黑色,否则会继续向上保持循环;
情况 3 会转变为情况 4,对于情况 4,会将 x 设为根,然后退出循环并将根着成黑色。
综上可知树根一定是黑色的。

13.4-2
如果 x x.p 都是红色,显然调用RB-DELETE-FIXUP不会进人循环,直接将 x 着成黑色。

13.4-3
这里写图片描述

13.4-4
RB-DELETE中的结点 y 没有孩子时,那么结点 x=T.nil ,因此RB-DELETE-FIXUP的第 2 行会检查。
当删除根结点时 x=T.nil 并且此时的根是 x ,在RB-DELETE-FIXUP的第 23 会将 x 着成黑色。

13.4-5
情况 1:转换前根结点到子树 α,β 的黑结点数是 3(结点 x 是双黑),到 γ,δ,ϵ,ζ 都是 2。转换后根结点到子树 α,β 的黑结点数是 3,到 γ,δ,ϵ,ζ 都是 2。

情况 2:转换前根结点到子树 α,β,γ,δ,ϵ,ζ 的黑结点数是 2+count(c)。转换后新结点 x 有一个属性值 c,它是红黑或者双黑。若转换前是红色,那么原count(c)=0,转换后count(c)=1,否则原count(c)=1,转换后count(c)=2,因此转换后根结点到子树 α,β,γ,δ,ϵ,ζ 的黑结点数没变。

情况 3、4 可以根据情况 2 类似得到,在此略。

13.4-6
情况 1 发生时, x 的兄弟结点 w 是红色,如果 x.p 是红色,也就是 w.p 是红色,此时已经违反了红黑树的性质,我们都不可能调用RB-DELETE

13.4-7
可能一样也可能不一样,下面给两个简单的例子,例一是树形改变,例二是树形一样但结点颜色变化。

这里写图片描述

附上红黑树代码(注释很少,基本上和书上的伪代码一样,看得懂伪代码应该就能看懂下面的代码)。

#include <iostream>
#include <climits>
#include <iomanip>
using std::cout;
using std::endl;

enum COLOR
{
    RED = 0,BLACK = 1
};

struct RB_TREE
{
    int key;
    COLOR color;
    RB_TREE *parent;
    RB_TREE *left;
    RB_TREE *right;
};

RB_TREE nil = {INT_MIN,BLACK,NULL,NULL,NULL};//简单初始化一下哨兵,其实能用到的只是哨兵的颜色

void LEFT_ROTATE(RB_TREE **root,RB_TREE *x)
{
    if(x->right != &nil)    //x的右孩子为哨兵,直接返回
    {
        RB_TREE *y = x->right;
        x->right = y->left;
        if(y->left != &nil)
            y->left->parent = x;
        y->parent = x->parent;
        if(x->parent == &nil)
            *root = y;
        else if(x == x->parent->left)
            x->parent->left = y;
        else x->parent->right = y;
        y->left = x;
        x->parent = y;
    }
    else return;
}

void RIGHT_ROTATE(RB_TREE **root,RB_TREE *x)
{
    if(x->left != &nil)
    {
        RB_TREE *y = x->left;
        x->left = y->right;
        if(y->right != &nil)
            y->right->parent = x;
        y->parent = x->parent;
        if(x->parent == &nil)
            *root = y;
        else if(x == x->parent->left)
            x->parent->left = y;
        else x->parent->right = y;
        y->right = x;
        x->parent = y;
    }
}

RB_TREE *SEARCH(RB_TREE *root,int key)
{
    if(root == &nil || root->key == key)
        return root;
    else if(root->key > key)
        return SEARCH(root->left,key);
    else return SEARCH(root->right,key);
}

RB_TREE *MINIMUM(RB_TREE *root)
{
    if(root == &nil || root->left == &nil)
        return root;
    else return MINIMUM(root->left);
}

RB_TREE *MAXIMUM(RB_TREE *root)
{
    if(root == &nil || root->right == &nil)
        return root;
    else return MAXIMUM(root->right);
}

RB_TREE *SUCCESSOR(RB_TREE *p)
{
    if(p == &nil)
        return p;
    if(p->right != &nil)
        return MINIMUM(p->right);
    RB_TREE *x = p->parent;
    while(x != &nil && p == x->right)
    {
        p = x;
        x = x->parent;
    }
    return x;
}

RB_TREE *PREDECESSOR(RB_TREE *p)
{
    if(p == &nil)
        return p;
    if(p->left != &nil)
        return MAXIMUM(p->left);
    RB_TREE *x = p->parent;
    while(x != &nil && p == x->left)
    {
        p = x;
        x = x->parent;
    }
    return x;
}

void RB_INSERT_FIXUP(RB_TREE **root,RB_TREE *z)
{
    while(z->parent->color == RED)
    {
        if(z->parent == z->parent->parent->left)
        {
            RB_TREE *y = z->parent->parent->right;
            if(y->color == RED)
            {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else
            {
                if(z == z->parent->right)
                {
                    z = z->parent;
                    LEFT_ROTATE(root,z);
                }
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                RIGHT_ROTATE(root,z->parent->parent);
            }
        }
        else
        {
            RB_TREE *y = z->parent->parent->left;
            if(y->color == RED)
            {
                z->parent->color = BLACK;
                y->color = BLACK;
                z->parent->parent->color = RED;
                z = z->parent->parent;
            }
            else
            {
                if(z == z->parent->left)
                {
                    z = z->parent;
                    RIGHT_ROTATE(root,z);
                }
                z->parent->color = BLACK;
                z->parent->parent->color = RED;
                LEFT_ROTATE(root,z->parent->parent);
            }
        }
    }
    (*root)->color = BLACK;
}

void RB_INSERT(RB_TREE **root,int key)
{
    RB_TREE *y = &nil;
    RB_TREE *x = *root;
    while(x != &nil)
    {
        y = x;
        if(x->key > key)
            x = x->left;
        else x = x->right;
    }
    RB_TREE *z = new RB_TREE;
    z->parent = y;
    if(y == &nil)
        *root = z;
    else if(key < y->key)
        y->left = z;
    else y->right = z;
    z->key = key;
    z->left = z->right = &nil;
    z->color = RED;
    RB_INSERT_FIXUP(root,z);
}

void RB_TRANSPLANT(RB_TREE **root,RB_TREE *u,RB_TREE *v)
{
    if(u->parent == &nil)
        *root = v;
    else if(u == u->parent->left)
        u->parent->left = v;
    else u->parent->right = v;
    v->parent = u->parent;
}

void RB_DELETE_FIXUP(RB_TREE **root,RB_TREE *x)
{
    while(x != *root && x->color == BLACK)
    {
        if(x == x->parent->left)
        {
            RB_TREE *w = x->parent->right;
            if(w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                LEFT_ROTATE(root,x->parent);
                w = x->parent->right;
            }
            if(w->left->color == BLACK && w->right->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if(w->right->color == BLACK)
                {
                    w->left->color = BLACK;
                    w->color = RED;
                    RIGHT_ROTATE(root,w);
                    w = x->parent->right;
                }
                w->color = x->parent->color;
                x->parent->color = BLACK;
                w->right->color = BLACK;
                LEFT_ROTATE(root,x->parent);
                x = *root;
            }
        }
        else
        {
            RB_TREE *w = x->parent->left;
            if(w->color == RED)
            {
                w->color = BLACK;
                x->parent->color = RED;
                RIGHT_ROTATE(root,x->parent);
                w = x->parent->left;
            }
            if(w->left->color == BLACK && w->right->color == BLACK)
            {
                w->color = RED;
                x = x->parent;
            }
            else
            {
                if(w->left->color == BLACK)
                {
                    w->right->color = BLACK;
                    w->color = RED;
                    LEFT_ROTATE(root,w);
                    w = x->parent->left;
                }
                w->color = x->parent->color;
                x->parent->color = BLACK;
                w->left->color = BLACK;
                RIGHT_ROTATE(root,x->parent);
                x = *root;
            }
        }
    }
    x->color = BLACK;
}

void RB_DELETE(RB_TREE **root, int key)
{
    RB_TREE *z = SEARCH(*root,key);
    if(z == &nil)
        return;
    RB_TREE *y = z;
    COLOR y_original_color = y->color;
    RB_TREE *x;
    if(z->left == &nil)
    {
        x = z->right;
        RB_TRANSPLANT(root,z,z->right);
    }
    else if(z->right == &nil)
    {
        x = z->left;
        RB_TRANSPLANT(root,z,z->left);
    }
    else
    {
        y = MINIMUM(z->right);
        y_original_color = y->color;
        x = y->right;
        if(y->parent == z)
            x->parent = y;
        else
        {
            RB_TRANSPLANT(root,y,y->right);
            y->right = z->right;
            y->right->parent = y;
        }
        RB_TRANSPLANT(root,z,y);
        y->left = z->left;
        y->left->parent = y;
        y->color = z->color;
    }
    if(y_original_color == BLACK)
        RB_DELETE_FIXUP(root,x);
    delete z;
}

void preOrder(RB_TREE *root)
{
    if(root != &nil)
    {
        cout << "key is: " << std::setw(3) << root->key << ' ' << " and color is: ";
        if(root->color == BLACK)
            cout << "BLACK" << endl;
        else cout << "RED" << endl;
        preOrder(root->left);
        preOrder(root->right);
    }
}

void inOrder(RB_TREE *root)
{
    if(root != &nil)
    {
        inOrder(root->left);
        cout << "key is: " << std::setw(3) << root->key << ' ' << " and color is: ";
        if(root->color == BLACK)
            cout << "BLACK" << endl;
        else cout << "RED" << endl;
        inOrder(root->right);
    }
}

void postOrder(RB_TREE *root)
{
    if(root != &nil)
    {
        postOrder(root->left);
        postOrder(root->right);
        cout << "key is: " << std::setw(3) << root->key << ' ' << " and color is: ";
        if(root->color == BLACK)
            cout << "BLACK" << endl;
        else cout << "RED" << endl;
    }
}

int main()
{
    int ia[] = {41,38,31,12,19,8};
    RB_TREE *root = &nil;
    for(int i = 0; i < 6; ++i)       //创建红黑树
        RB_INSERT(&root,ia[i]);
    cout << "preOder is" << endl;
    preOrder(root);
    cout << endl;
    cout << "inOder is" << endl;
    inOrder(root);
    cout << endl;
    cout << "postOder is" << endl;
    postOrder(root);
    cout << endl;

    RB_DELETE(&root,8);              //删除关键字8的结点
    cout << "after delete key 8:" << endl;
    cout << "preOder is" << endl;
    preOrder(root);
    cout << endl;
    cout << "inOder is" << endl;
    inOrder(root);
    cout << endl;
    cout << "postOder is" << endl;
    postOrder(root);
    cout << endl;

    RB_DELETE(&root,12);             //删除关键字12的结点
    cout << "after delete key 12:" << endl;
    cout << "preOder is" << endl;
    preOrder(root);
    cout << endl;
    cout << "inOder is" << endl;
    inOrder(root);
    cout << endl;
    cout << "postOder is" << endl;
    postOrder(root);
    cout << endl;

    RB_DELETE(&root,19);              //删除关键字19的结点
    cout << "after delete key 19:" << endl;
    cout << "preOder is" << endl;
    preOrder(root);
    cout << endl;
    cout << "inOder is" << endl;
    inOrder(root);
    cout << endl;
    cout << "postOder is" << endl;
    postOrder(root);

    cout << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值