红黑树删除操作
实验目的
实现红黑树的删除操作:基于之前建立的红黑树,编写红黑树删除程序删除给定的一个结点。
实验原理
与n个结点的红黑树上的其他基本操作一样,删除一个结点要花费O(lgn)时间。当要删除一个结点z时,可以分为两种情况:(1)当z的子结点少于2个时,z从树中删除,并让y成为z;(2)当z有两个子结点时,y应该是z的后继,并且y将移至树中的z位置,在结点被移除或者在树中移动之前,必须记住y的颜色,并且记录结点x的踪迹,将x移至树中y的原来位置,因为结点x也可能引起红黑性质的破坏。删除结点z之后,需要调用RB-DELETE-FIXUP来对使删除后的树满足红黑树的性质。
实验过程
RB-TRANSPLANT(T, u,v)
1 if u.p == T.nil
2 T.root = v
3 else if u ==u.p.left
4 u.p.left = v
5 else u.p.right =v
6 v.p = u.p
RB-DELETE(T, z)
1 y = z
2 y-original-color= y.color
3 if z.left == T.nil
4 x = z.right
5 RB-TRANSPLANT(T, z, z.right)
6 elseif z.right== T.nil
7 x = z.left
8 RB-TRANSPLANT(T, z, z.left)
9 else y =TREE-MINIMUM(z.right)
10 y-original-color = y.color
11 x = y.right
12 if y.p == z
13 x.p = y
14 else RB-TRANSPLANT(T, y, y.right)
15 y.right = z.right
16 y.right.p = y
17 RB-TRANSPLANT(T, z, y)
18 y.left = z.left
19 y.left.p = y
20 y.color = z.color
21 if y-original-color == BLACK
22 RB-DELETE-FIXUP(T, x)
RB-DELETE-FIXUP(T,x)
1 while x != T.root and x.color == BLACK
2 if x == x.p.left
3 w = x.p.right
4 if w.color == RED
5 w.color = BLACK
6 x.p.color = RED
7 LEFT-ROTATE(T, x, p)
8 w = x.p.right
9 if w.left.color == BLACK andw.right.color == BLACK
10 w.color = RED
11 x = x.p
12 else if w.right.color == BLACK
13 w.left.color = BLACK
14 w.color = RED
15 RIGHT-ROTATE(T, w)
16 w = x.p.right
17 w.color = x.p.color
18 x.p.color = BLACK
19 w.right.color = BLACK
20 LEFT-ROTATE(T, x, p)
21 x = T.root
22 else(same as then clause with “right”and “left” exchanged)
23 x.color = BLACK
首先构建一个有9个结点的红黑树,树根结点的key值为7:
构建的9个结点的红黑树,最后一个元素是15:
对于构建好的9个结点的红黑树,对其进行删除,删除3个结点,首先删除的结点的key值为11:
删除三个结点(key = 11, 4, 2)后的红黑树:
实验总结
(一)整个红黑树实验结束,关于红黑树的插入和删除操作,相对于二叉搜索树而言,对于key的处理相似,只是红黑树操作过程中,必须保证红黑树在操作前后满足红黑树的五个性质,因此红黑树较复杂,也就是一种trade off,即通过增加树的其他性质,来保证树高能近似于O(lgn);
(二)在实现红黑树算法的过程中,一定要先去理解红黑树的算法原理,这样才能在调试的过程中,很轻松地发现出现问题的代码;在实现红黑树的插入算法过程中,也发现了书中的一个小错误:《算法导论》第三版,机械工业出版社,在书中P179实现RB-INSERT-FIXUP(T, z)算法的12行,处理case3时应该加一个else,因为case1、2、3是三种独立的情况,理解原理后很容易区分出来。
(三)独立处理完之前的几个算法实验后,感觉对于数据结构以及算法优化有了一点点感觉,且行且学习吧!
附录(代码)
#include <stdio.h>
#include <stdlib.h>
typedef structnode *tree_pointer;
typedef struct node {
int key;
char color; //R represents red; B represents black
tree_pointerp;
tree_pointerleft;
tree_pointerright;
} *tree_pointer;
void RB_insert(tree_pointer T_nil, tree_pointerT_root, tree_pointer z);
void left_rotate(tree_pointer T_nil, tree_pointerT_root, tree_pointer x);
void right_rotate(tree_pointer T_nil, tree_pointerT_root, tree_pointer x);
void RB_insert_fixup(tree_pointer T_nil, tree_pointerT_root, tree_pointer z);
void print_tree(tree_pointer T_root, int n);
void RB_transplant(tree_pointer T_nil, tree_pointerT_root, tree_pointer u, tree_pointer v);
void RB_delete(tree_pointer T_nil, tree_pointerT_root, tree_pointer z);
void RB_delete_fixup(tree_pointer T_nil, tree_pointerT_root, tree_pointer x);
int get_tree_height(tree_pointer T_root);
struct node * creat_node(tree_pointer T, int key);
struct node * tree_minimum(tree_pointer T_nil,tree_pointer x);
struct node * tree_search(tree_pointer T_nil,tree_pointer x, int k);
int main(){
inti,num,key,tree_height;
tree_pointernew_node = NULL;
tree_pointerT_root = NULL;
tree_pointerT_nil = NULL;
T_nil =(struct node *)malloc(sizeof(struct node));
T_nil->color= 'B';
T_root =(struct node *)malloc(sizeof(struct node));
T_root->color= 'B';
T_root->p = T_nil;
T_root->left = T_nil;
T_root->right= T_nil;
printf("T_nil= %p; key = %d; color = %c; p = %p; left = %p; right = %p\n",T_nil,T_nil->key, T_nil->color, T_nil->p, T_nil->left, T_nil->right);
printf("T_root= %p; key = %d; color = %c; p = %p; left = %p; right = %p\n",T_root,T_root->key, T_root->color, T_root->p, T_root->left,T_root->right);
printf("pleaseinput the number of nodes:");
scanf("%d",&num);
printf("pleaseinput the key:");
scanf("%d",&key);
T_root->key= key;
printf("\n");
tree_height =get_tree_height(T_root);
print_tree(T_root,tree_height);
printf("\n");
for(i = 0; i< num-1; i++){
printf("pleaseinput the key:");
scanf("%d",&key);
printf("\n");
new_node =creat_node(T_nil, key);
RB_insert(T_nil,T_root, new_node);
// tree_height= get_tree_height(T_root);
// print_tree(T_root,tree_height);
// printf("\n666666666666666666666666\n");
}
tree_pointerdelete_node;
printf("inputthe number of deleting node:");
scanf("%d",&num);
for(i = 0; i< num; i++){
printf("thekey of deleting node:");
scanf("%d",&key);
printf("\n");
delete_node= tree_search(T_nil, T_root, key);
RB_delete(T_nil,T_root, delete_node);
// tree_height = get_tree_height(T_root);
// print_tree(T_root, tree_height);
}
}
struct node * tree_search(tree_pointer T_nil,tree_pointer x, int k){
if(x == T_nil|| k == x->key)
return x;
if(k <x->key)
returntree_search(T_nil, x->left, k);
else
returntree_search(T_nil, x->right, k);
}
struct node * creat_node(tree_pointer T, int key){
tree_pointernew = NULL;
new = (structnode *)malloc(sizeof(struct node));
new->key = key;
new->color= 'R';
new->p = T;
new->left = T;
new->right= T;
return new;
}
void RB_insert(tree_pointer T_nil, tree_pointerT_root, tree_pointer z){
tree_pointerx = NULL;
tree_pointery = NULL;
y = T_nil;
x = T_root;
//printf("\nnowRB_insert is running!\n");
while(x !=T_nil){
y = x;
if(z->key< x->key)
x =x->left;
else
x =x->right;
}
z->p = y;
if(y ==T_nil)
T_root = z;
elseif(z->key < y->key)
y->left = z;
else
y->right= z;
z->left = T_nil;
z->right =T_nil;
z->color ='R';
RB_insert_fixup(T_nil,T_root, z);
// printf("\nnowRB_insert is over!\n");
}
void RB_insert_fixup(tree_pointer T_nil, tree_pointerT_root, tree_pointer z){
tree_pointery = NULL;
// printf("\nnowRB_insert_fixup is running!\n");
while(z->p->color== 'R'){
if(z->p== z->p->p->left){
y =z->p->p->right;
if(y->color== 'R'){
z->p->color = 'B';
y->color = 'B';
z->p->p->color= 'R';
z =z->p->p;
}
elseif(z == z->p->right){
z =z->p;
left_rotate(T_nil,T_root, z);
}
else{
z->p->color = 'B';
z->p->p->color= 'R';
right_rotate(T_nil,T_root, z->p->p);
}
}
//
elseif(z->p = z->p->p->right){
y =z->p->p->left;
if(y->color== 'R'){
z->p->color = 'B';
y->color = 'B';
z->p->p->color= 'R';
z =z->p->p;
}
elseif(z == z->p->left){
z =z->p;
right_rotate(T_nil,T_root, z);
}
else{
z->p->color = 'B';
z->p->p->color= 'R';
left_rotate(T_nil,T_root, z->p->p);
}
}
T_root->color= 'B';
}
// printf("\nnowRB_insert_fixup is over!\n");
int tree_height;
if(T_root->p== T_nil){
tree_height= get_tree_height(T_root);
print_tree(T_root,tree_height);
}
else{
tree_height= get_tree_height(T_root);
print_tree(T_root->p,tree_height);
}
}
void left_rotate(tree_pointer T_nil, tree_pointer T_root,tree_pointer x){
tree_pointery = NULL;
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;
}
void right_rotate(tree_pointer T_nil, tree_pointerT_root, tree_pointer x){
tree_pointery = NULL;
y =x->left;
x->left =y->right;
if(y->right!= T_nil)
y->right->p= x;
y->p =x->p;
if(x->p ==T_nil)
T_root =y;
else if(x ==x->p->right)
x->p->right= y;
else
x->p->left= y;
y->right =x;
x->p = y;
}
int get_tree_height(tree_pointer T_root){
if(!T_root)
return 0;
intleft_height,right_height;
left_height = get_tree_height(T_root->left);
right_height= get_tree_height(T_root->right);
return(left_height < right_height)?(right_height+1):(left_height+1);
}
void print_tree(tree_pointer T_root, int n){
int i;
if(T_root ==NULL)
return;
print_tree(T_root->right,n-1);
for(i = 0; i< n-1; i++)
printf(" ");
if(n > 0){
printf("---");
printf("%d(%c)\n",T_root->key,T_root->color);
}
print_tree(T_root->left,n-1);
}
void RB_transplant(tree_pointer T_nil, tree_pointerT_root, tree_pointer u, tree_pointer v){
// printf("\nbeforeRB_transplant: u->p = %p; v->p = %p;\n",u->p, v->p);
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;
/*
inttree_height;
tree_height =get_tree_height(T_root);
print_tree(T_root,tree_height);
*/
// printf("\nlater RB_transplant: u->p = %p; v->p = %p;\n",u->p, v->p);
}
void RB_delete(tree_pointer T_nil, tree_pointerT_root, tree_pointer z){
tree_pointery = NULL;
tree_pointerx = NULL;
chary_original_color;
y = z;
y_original_color= y->color;
if(z->left== T_nil){
// printf("\nz->left== T_nil !!!!!!!!!!\n");
// printf("beforez = %p; z->right = %p\n", z, z->right);
x =z->right;
RB_transplant(T_nil,T_root, z, z->right);
// printf("later z = %p; z->p->right = %p\n", z, z->p->right);
}
elseif(z->right == T_nil){
x =z->left;
RB_transplant(T_nil,T_root, z, z->left);
}
else{
y =tree_minimum(T_nil, z->right);
// printf("\nTREE_MINIMUM!!!!!!!!!!!!!!!\n");
// printf("y->key= %d\n",y->key);
y_original_color= y->color;
x =y->right;
if(y->p== z)
x->p= y;
else{
RB_transplant(T_nil,T_root, y, y->right);
y->right= z->right;
y->right->p= y;
}
RB_transplant(T_nil,T_root, z, y);
y->left= z->left;
y->left->p= y;
y->color= z->color;
// printf("\nNNNNNNNNNNNNNNNNNNNNNNNNNN\n");
}
if(y_original_color== 'B')
RB_delete_fixup(T_nil,T_root, x);
else{
inttree_height;
tree_height= get_tree_height(T_root);
print_tree(T_root,tree_height);
}
}
struct node * tree_minimum(tree_pointer T_nil,tree_pointer x){
while(x->left!= T_nil)
x =x->left;
return x;
}
void RB_delete_fixup(tree_pointer T_nil, tree_pointerT_root, tree_pointer x){
tree_pointerw = NULL;
w = (structnode *)malloc(sizeof(struct node));
while(x != T_root&& x->color == 'B'){
if(x ==x->p->left){
w =x->p->right;
if(w->color== 'R'){
w->color= 'B';
x->p->color= 'R';
left_rotate(T_nil,T_root, x->p);
w =x->p->right;
}
if(w->left->color== 'B' && w->right->color == 'B'){
w->color= 'R';
x =x->p;
}
elseif(w->right->color == 'B'){
w->left->color= 'B';
w->color= 'R';
right_rotate(T_nil,T_root, w);
w =x->p->right;
}
else{
w->color= x->p->color;
x->p->color= 'B';
w->right->color= 'B';
left_rotate(T_nil,T_root, x->p);
x =T_root;
}
}
else{
w =x->p->left;
if(w->color== 'R'){
w->color= 'B';
x->p->color= 'R';
right_rotate(T_nil,T_root, x->p);
w =x->p->left;
}
if(w->right->color== 'B' && w->left->color == 'B'){
w->color = 'R';
x = x->p;
}
elseif(w->left->color == 'B'){
w->right->color= 'B';
w->color= 'R';
left_rotate(T_nil,T_root, w);
w =x->p->left;
}
else{
w->color= x->p->color;
x->p->color= 'B';
w->left->color= 'B';
right_rotate(T_nil,T_root, x->p);
x =T_root;
}
}
}
x->color ='B';
inttree_height;
tree_height =get_tree_height(T_root);
print_tree(T_root,tree_height);
}