红黑树删除操作

红黑树删除操作

实验目的

实现红黑树的删除操作:基于之前建立的红黑树,编写红黑树删除程序删除给定的一个结点。

 

实验原理

与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);

}

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值