算法导论13(红黑树)

插入
当前结点z为红色,父结点z->p为红色:
(1)叔结点为红色:
z->p和z->p->p->right着为黑色,z->p->p着为红色,z=z->p->p,循环。

这里写图片描述

(2)叔结点为黑色,且当前结点z为右孩子:
z=z->p,左旋z,转换为(3)。

(3)叔结点为黑色,且当前结点z为左孩子:
交换z->p和z->p->p的颜色,右旋z->p->p,跳出循环,root着为黑色。

这里写图片描述

删除
在while循环中,x总是指向一个具有双重黑色的非根结点。while循环的目标是将额外的黑色沿树上移,直到:
(1)x指向红黑结点,此时在最后一行中,将x着为(单个)黑色;
(2)x指向根结点,此时可以简单地“移除”额外的黑色;
(3)执行适当的旋转和重新着色,退出循环。

x指向一个具有双重黑色的非根结点:
(1)x的兄弟结点w是红色的:
交换x->p和w的颜色,左旋x->p,w=x->p->right,转换为(2)、(3)或(4)。

(2)x的兄弟结点w是黑色的,且w的两个孩子都是黑色的:
w着为红色,x=x->p(额外的黑色沿树上移),循环。

这里写图片描述

(3)x的兄弟结点w是黑色的,且w的左孩子是红色的,右孩子是黑色的:
交换w和w->left的颜色,右旋w,w=x->p->right,转换为(4)。

(4)x的兄弟结点w是黑色的,且w的右孩子是红色的:
交换x->p和w的颜色,w->right着为黑色,左旋x->p,x=root,跳出循环,x着为黑色。

这里写图片描述

const int RED=0,BLACK=1;

struct node
{
    int key,color;
    node *left,*right,*p;
    node():color(BLACK){}
};

node *nil=new node;

node *treeMinimum(node *x)
{
    while(x->left!=nil)x=x->left;
    return x;
}

node *treeMaximum(node *x)
{
    while(x->right!=nil)x=x->right;
    return x;
}

void leftRotate(node *&root,node *x)
{
    node *y=x->right;
    x->right=y->left;
    if(y->left!=nil)y->left->p=x;
    y->p=x->p;
    if(x->p==nil)root=y;
    else if(x==x->p->left)x->p->left=y;
    else x->p->right=y;
    y->left=x;
    x->p=y;
}

void rightRotate(node *&root,node *x)
{
    node *y=x->left;
    x->left=y->right;
    if(y->right!=nil)y->right->p=x;
    y->p=x->p;
    if(x->p==nil)root=y;
    else if(x==x->p->left)x->p->left=y;
    else x->p->right=y;
    y->right=x;
    x->p=y;
}

void RBInsertFixup(node *&root,node *z)
{
    while(z->p->color==RED)
    {
        if(z->p==z->p->p->left)
        {
            node *y=z->p->p->right;
            if(y->color==RED)
            {
                z->p->color=y->color=BLACK;
                z->p->p->color=RED;
                z=z->p->p;
            }
            else 
            {
                if(z==z->p->right)
                {
                    z=z->p;
                    leftRotate(root,z);
                }
                z->p->color=BLACK;
                z->p->p->color=RED;
                rightRotate(root,z->p->p);
            }
        }
        else
        {
            node *y=z->p->p->left;
            if(y->color==RED)
            {
                z->p->color=y->color=BLACK;
                z->p->p->color=RED;
                z=z->p->p;
            }
            else 
            {
                if(z==z->p->left)
                {
                    z=z->p;
                    rightRotate(root,z);
                }
                z->p->color=BLACK;
                z->p->p->color=RED;
                leftRotate(root,z->p->p);
            }
        }
    }
    root->color=BLACK;
}

void RBInsert(node *&root,node *z)
{
    node *y=nil;
    node *x=root;
    while(x!=nil)
    {
        y=x;
        if(z->key<x->key)x=x->left;
        else x=x->right;
    }
    z->p=y;
    if(y==nil)root=z;
    else if(z->key<y->key)y->left=z;
    else y->right=z;
    z->left=z->right=nil;
    z->color=RED;
    RBInsertFixup(root,z);
}

void RBTransplant(node *&root,node *u,node *v)
{
    if(u->p==nil)root=v;
    else if(u==u->p->left)u->p->left=v;
    else u->p->right=v;
    v->p=u->p;
}

void RBDeleteFixup(node *&root,node *x)
{
    while(x!=root&&x->color==BLACK)
    {
        node *w;
        if(x==x->p->left)
        {
            w=x->p->right;
            if(w->color==RED)
            {
                w->color=BLACK;
                x->p->color=RED;
                leftRotate(root,x->p);
                w=x->p->right;
            }
            if(w->left->color==BLACK&&w->right->color==BLACK)
            {
                w->color=RED;
                x=x->p;
            }
            else 
            {
                if(w->right->color==BLACK)
                {
                    w->left->color=BLACK;
                    w->color=RED;
                    rightRotate(root,w);
                    w=x->p->right;
                }
                w->color=x->p->color;
                x->p->color=BLACK;
                w->right->color=BLACK;
                leftRotate(root,x->p);
                x=root;
            }
        }
        else
        {
            w=x->p->left;
            if(w->color==RED)
            {
                w->color=BLACK;
                x->p->color=RED;
                rightRotate(root,x->p);
                w=x->p->left;
            }
            if(w->left->color==BLACK&&w->right->color==BLACK)
            {
                w->color=RED;
                x=x->p;
            }
            else 
            {
                if(w->left->color==BLACK)
                {
                    w->right->color=BLACK;
                    w->color=RED;
                    leftRotate(root,w);
                    w=x->p->left;
                }
                w->color=x->p->color;
                x->p->color=BLACK;
                w->left->color=BLACK;
                rightRotate(root,x->p);
                x=root;
            }
        }
    }
    x->color=BLACK;
}

//直接前驱
void RBDelete(node *&root,node *z)
{
    node *y=z,*x;
    int yOriginalColor=y->color;
    if(z->left==nil)
    {
        x=z->right;
        RBTransplant(root,z,z->right);
    }
    else if(z->right==nil)
    {
        x=z->left;
        RBTransplant(root,z,z->left);
    }
    else
    {
        y=treeMaximum(z->left);
        yOriginalColor=y->color;
        x=y->left;
        if(y->p==z)x->p=y;
        else
        {
            RBTransplant(root,y,y->left);
            y->left=z->left;
            y->left->p=y;
        }
        RBTransplant(root,z,y);
        y->right=z->right;
        y->right->p=y;
        y->color=z->color;
    }
    delete z;
    if(yOriginalColor==BLACK)RBDeleteFixup(root,x);
}

//直接后继
void RBDelete(node *&root,node *z)
{
    node *y=z,*x;
    int yOriginalColor=y->color;
    if(z->left==nil)
    {
        x=z->right;
        RBTransplant(root,z,z->right);
    }
    else if(z->right==nil)
    {
        x=z->left;
        RBTransplant(root,z,z->left);
    }
    else
    {
        y=treeMinimum(z->right);
        yOriginalColor=y->color;
        x=y->right;
        if(y->p==z)x->p=y;
        else
        {
            RBTransplant(root,y,y->right);
            y->right=z->right;
            y->right->p=y;
        }
        RBTransplant(root,z,y);
        y->left=z->left;
        y->left->p=y;
        y->color=z->color;
    }
    delete z;
    if(yOriginalColor==BLACK)RBDeleteFixup(root,x);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值