插入
当前结点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);
}