zoukankan      html  css  js  c++  java
  • 红黑树删除操作

    红黑树删除操作

    实验目的

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

    实验原理

    与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是三种独立的情况,理解原理后很容易区分出来。

    (三)独立处理完之前的几个算法实验后,感觉对于数据结构以及算法优化有了一点点感觉,且行且学习吧!

    附录(代码)

      1 #include <stdio.h>
      2 
      3 #include <stdlib.h>
      4 
      5  
      6 
      7 typedef  structnode *tree_pointer;
      8 
      9 typedef struct node {
     10 
     11     int  key;
     12 
     13     char color;       //R represents red; B represents black
     14 
     15     tree_pointerp;
     16 
     17     tree_pointerleft;
     18 
     19     tree_pointerright;
     20 
     21 } *tree_pointer;
     22 
     23  
     24 
     25 void RB_insert(tree_pointer T_nil, tree_pointerT_root, tree_pointer z);
     26 
     27 void left_rotate(tree_pointer T_nil, tree_pointerT_root, tree_pointer x);
     28 
     29 void right_rotate(tree_pointer T_nil, tree_pointerT_root, tree_pointer x);
     30 
     31 void RB_insert_fixup(tree_pointer T_nil, tree_pointerT_root, tree_pointer z);
     32 
     33 void print_tree(tree_pointer T_root, int n);
     34 
     35 void RB_transplant(tree_pointer T_nil, tree_pointerT_root, tree_pointer u, tree_pointer v);
     36 
     37 void RB_delete(tree_pointer T_nil, tree_pointerT_root, tree_pointer z);
     38 
     39 void RB_delete_fixup(tree_pointer T_nil, tree_pointerT_root, tree_pointer x);
     40 
     41  
     42 
     43 int get_tree_height(tree_pointer T_root);
     44 
     45  
     46 
     47 struct node * creat_node(tree_pointer T, int key);
     48 
     49 struct node * tree_minimum(tree_pointer T_nil,tree_pointer x);
     50 
     51 struct node * tree_search(tree_pointer T_nil,tree_pointer x, int k);
     52 
     53  
     54 
     55 int main(){
     56 
     57     inti,num,key,tree_height;
     58 
     59  
     60 
     61     tree_pointernew_node = NULL;
     62 
     63     tree_pointerT_root   = NULL;
     64 
     65     tree_pointerT_nil    = NULL;
     66 
     67     T_nil =(struct node *)malloc(sizeof(struct node));
     68 
     69     T_nil->color= 'B';
     70 
     71    
     72 
     73     T_root =(struct node *)malloc(sizeof(struct node));
     74 
     75     T_root->color= 'B';
     76 
     77     T_root->p     = T_nil;
     78 
     79     T_root->left  = T_nil;
     80 
     81     T_root->right= T_nil;
     82 
     83  
     84 
     85     printf("T_nil= %p; key = %d; color = %c; p = %p; left = %p; right = %p
    ",T_nil,T_nil->key, T_nil->color, T_nil->p, T_nil->left, T_nil->right);
     86 
     87     printf("T_root= %p; key = %d; color = %c; p = %p; left = %p; right = %p
    ",T_root,T_root->key, T_root->color, T_root->p, T_root->left,T_root->right);
     88 
     89    
     90 
     91     printf("pleaseinput the number of nodes:");
     92 
     93     scanf("%d",&num);
     94 
     95     printf("pleaseinput the key:");
     96 
     97     scanf("%d",&key);
     98 
     99     T_root->key= key;
    100 
    101     printf("
    ");
    102 
    103     tree_height =get_tree_height(T_root);
    104 
    105     print_tree(T_root,tree_height);
    106 
    107  
    108 
    109     printf("
    ");
    110 
    111     for(i = 0; i< num-1; i++){
    112 
    113        printf("pleaseinput the key:");
    114 
    115        scanf("%d",&key);
    116 
    117        printf("
    ");
    118 
    119        new_node =creat_node(T_nil, key);
    120 
    121        RB_insert(T_nil,T_root, new_node);
    122 
    123 //     tree_height= get_tree_height(T_root);
    124 
    125 //     print_tree(T_root,tree_height);
    126 
    127 //     printf("
    666666666666666666666666
    ");
    128 
    129     }
    130 
    131  
    132 
    133    
    134 
    135     tree_pointerdelete_node;
    136 
    137     printf("inputthe number of deleting node:");
    138 
    139     scanf("%d",&num);
    140 
    141     for(i = 0; i< num; i++){
    142 
    143        printf("thekey of deleting node:");
    144 
    145        scanf("%d",&key);
    146 
    147        printf("
    ");
    148 
    149        delete_node= tree_search(T_nil, T_root, key);
    150 
    151        RB_delete(T_nil,T_root, delete_node);
    152 
    153     //  tree_height = get_tree_height(T_root);
    154 
    155     //  print_tree(T_root, tree_height);
    156 
    157     }
    158 
    159 }
    160 
    161  
    162 
    163 struct node * tree_search(tree_pointer T_nil,tree_pointer x, int k){
    164 
    165     if(x == T_nil|| k == x->key)
    166 
    167        return x;
    168 
    169     if(k <x->key)
    170 
    171        returntree_search(T_nil, x->left, k);
    172 
    173     else
    174 
    175        returntree_search(T_nil, x->right, k);
    176 
    177 }
    178 
    179  
    180 
    181 struct node * creat_node(tree_pointer T, int key){
    182 
    183     tree_pointernew = NULL;
    184 
    185     new = (structnode *)malloc(sizeof(struct node));
    186 
    187     new->key   = key;
    188 
    189     new->color= 'R';
    190 
    191     new->p     = T;
    192 
    193     new->left  = T;
    194 
    195     new->right= T;
    196 
    197     return new;
    198 
    199 }
    200 
    201  
    202 
    203 void RB_insert(tree_pointer T_nil, tree_pointerT_root, tree_pointer z){
    204 
    205     tree_pointerx = NULL;
    206 
    207     tree_pointery = NULL;
    208 
    209     y = T_nil;
    210 
    211     x = T_root;
    212 
    213  
    214 
    215     //printf("
    nowRB_insert is running!
    ");
    216 
    217  
    218 
    219     while(x !=T_nil){
    220 
    221        y = x;
    222 
    223        if(z->key< x->key)
    224 
    225            x =x->left;
    226 
    227        else
    228 
    229            x =x->right;
    230 
    231     }
    232 
    233  
    234 
    235     z->p = y;
    236 
    237     if(y ==T_nil)
    238 
    239        T_root   = z;
    240 
    241     elseif(z->key < y->key)
    242 
    243        y->left  = z;
    244 
    245     else
    246 
    247        y->right= z;
    248 
    249    
    250 
    251     z->left  = T_nil;
    252 
    253     z->right =T_nil;
    254 
    255     z->color ='R';
    256 
    257  
    258 
    259    
    260 
    261  
    262 
    263     RB_insert_fixup(T_nil,T_root, z);
    264 
    265  
    266 
    267 //  printf("
    nowRB_insert is over!
    ");
    268 
    269 }
    270 
    271  
    272 
    273 void RB_insert_fixup(tree_pointer T_nil, tree_pointerT_root, tree_pointer z){
    274 
    275     tree_pointery = NULL;
    276 
    277  
    278 
    279 //  printf("
    nowRB_insert_fixup is running!
    ");
    280 
    281    
    282 
    283     while(z->p->color== 'R'){
    284 
    285        if(z->p== z->p->p->left){
    286 
    287            y =z->p->p->right;
    288 
    289           
    290 
    291            if(y->color== 'R'){
    292 
    293               z->p->color    = 'B';
    294 
    295               y->color       = 'B';
    296 
    297               z->p->p->color= 'R';
    298 
    299               z =z->p->p;
    300 
    301            }
    302 
    303            elseif(z == z->p->right){
    304 
    305               z =z->p;
    306 
    307               left_rotate(T_nil,T_root, z);
    308 
    309            }
    310 
    311            else{
    312 
    313               z->p->color    = 'B';
    314 
    315               z->p->p->color= 'R';
    316 
    317               right_rotate(T_nil,T_root, z->p->p);
    318 
    319              
    320 
    321            }
    322 
    323        }
    324 
    325        //////////////////////////////////
    326 
    327        elseif(z->p = z->p->p->right){
    328 
    329            y =z->p->p->left;
    330 
    331  
    332 
    333            if(y->color== 'R'){
    334 
    335               z->p->color    = 'B';
    336 
    337               y->color       = 'B';
    338 
    339               z->p->p->color= 'R';
    340 
    341               z =z->p->p;
    342 
    343            }
    344 
    345            elseif(z == z->p->left){
    346 
    347               z =z->p;
    348 
    349               right_rotate(T_nil,T_root, z);
    350 
    351            }
    352 
    353            else{
    354 
    355               z->p->color    = 'B';
    356 
    357               z->p->p->color= 'R';
    358 
    359               left_rotate(T_nil,T_root, z->p->p);
    360 
    361            }
    362 
    363        }
    364 
    365        T_root->color= 'B';
    366 
    367     }
    368 
    369  
    370 
    371 //  printf("
    nowRB_insert_fixup is over!
    ");
    372 
    373     int tree_height;
    374 
    375     if(T_root->p== T_nil){
    376 
    377        tree_height= get_tree_height(T_root);
    378 
    379        print_tree(T_root,tree_height);
    380 
    381     }
    382 
    383     else{
    384 
    385        tree_height= get_tree_height(T_root);
    386 
    387        print_tree(T_root->p,tree_height);
    388 
    389     }
    390 
    391 }
    392 
    393  
    394 
    395  
    396 
    397 void left_rotate(tree_pointer T_nil, tree_pointer T_root,tree_pointer x){
    398 
    399     tree_pointery = NULL;     
    400 
    401     y =x->right;
    402 
    403    
    404 
    405     x->right =y->left;
    406 
    407     if(y->left!= T_nil)
    408 
    409        y->left->p= x;
    410 
    411  
    412 
    413     y->p =x->p;
    414 
    415     if(x->p ==T_nil)
    416 
    417        T_root =y;
    418 
    419     else if(x ==x->p->left)
    420 
    421        x->p->left= y;
    422 
    423     else
    424 
    425        x->p->right= y;
    426 
    427    
    428 
    429     y->left =x;
    430 
    431     x->p    = y;
    432 
    433 }
    434 
    435  
    436 
    437 void right_rotate(tree_pointer T_nil, tree_pointerT_root, tree_pointer x){
    438 
    439     tree_pointery = NULL;
    440 
    441     y =x->left;
    442 
    443  
    444 
    445     x->left =y->right;
    446 
    447     if(y->right!= T_nil)
    448 
    449        y->right->p= x;
    450 
    451    
    452 
    453     y->p =x->p;
    454 
    455     if(x->p ==T_nil)
    456 
    457        T_root =y;
    458 
    459     else if(x ==x->p->right)
    460 
    461        x->p->right= y;
    462 
    463     else
    464 
    465        x->p->left= y;
    466 
    467    
    468 
    469     y->right =x;
    470 
    471     x->p = y;
    472 
    473 }
    474 
    475  
    476 
    477 int get_tree_height(tree_pointer T_root){
    478 
    479     if(!T_root)
    480 
    481        return 0;
    482 
    483     intleft_height,right_height;
    484 
    485     left_height  = get_tree_height(T_root->left);
    486 
    487     right_height= get_tree_height(T_root->right);
    488 
    489     return(left_height < right_height)?(right_height+1):(left_height+1);
    490 
    491 }
    492 
    493  
    494 
    495 void print_tree(tree_pointer T_root, int n){
    496 
    497     int i;
    498 
    499     if(T_root ==NULL)
    500 
    501        return;
    502 
    503     print_tree(T_root->right,n-1);
    504 
    505  
    506 
    507     for(i = 0; i< n-1; i++)
    508 
    509         printf("   ");
    510 
    511     if(n > 0){
    512 
    513        printf("---");
    514 
    515        printf("%d(%c)
    ",T_root->key,T_root->color);
    516 
    517     }
    518 
    519    
    520 
    521     print_tree(T_root->left,n-1);
    522 
    523 }
    524 
    525  
    526 
    527  
    528 
    529 void RB_transplant(tree_pointer T_nil, tree_pointerT_root, tree_pointer u, tree_pointer v){
    530 
    531 //  printf("
    beforeRB_transplant: u->p = %p; v->p = %p;
    ",u->p, v->p);
    532 
    533     if(u->p ==T_nil)
    534 
    535        T_root =v;
    536 
    537     else if(u ==u->p->left)
    538 
    539        u->p->left= v;
    540 
    541     else
    542 
    543        u->p->right= v;
    544 
    545     v->p =u->p;
    546 
    547 /*
    548 
    549     inttree_height;
    550 
    551     tree_height =get_tree_height(T_root);
    552 
    553     print_tree(T_root,tree_height);
    554 
    555 */
    556 
    557 //  printf("
    later RB_transplant: u->p = %p; v->p = %p;
    ",u->p, v->p);
    558 
    559 }
    560 
    561  
    562 
    563 void RB_delete(tree_pointer T_nil, tree_pointerT_root, tree_pointer z){
    564 
    565     tree_pointery = NULL;
    566 
    567     tree_pointerx = NULL;
    568 
    569     chary_original_color;
    570 
    571  
    572 
    573     y = z;
    574 
    575     y_original_color= y->color;
    576 
    577  
    578 
    579     if(z->left== T_nil){
    580 
    581 //     printf("
    z->left== T_nil !!!!!!!!!!
    ");
    582 
    583 //     printf("beforez = %p; z->right = %p
    ", z, z->right);
    584 
    585        x =z->right;
    586 
    587        RB_transplant(T_nil,T_root, z, z->right);
    588 
    589 //     printf("later z = %p; z->p->right = %p
    ", z, z->p->right);
    590 
    591     }
    592 
    593     elseif(z->right == T_nil){
    594 
    595        x =z->left;
    596 
    597        RB_transplant(T_nil,T_root, z, z->left);
    598 
    599     }
    600 
    601     else{
    602 
    603        y =tree_minimum(T_nil, z->right);
    604 
    605 //     printf("
    TREE_MINIMUM!!!!!!!!!!!!!!!
    ");
    606 
    607 //     printf("y->key= %d
    ",y->key);
    608 
    609        y_original_color= y->color;
    610 
    611        x =y->right;
    612 
    613       
    614 
    615        if(y->p== z)
    616 
    617            x->p= y;
    618 
    619        else{
    620 
    621            RB_transplant(T_nil,T_root, y, y->right);
    622 
    623            y->right= z->right;
    624 
    625            y->right->p= y;
    626 
    627        }
    628 
    629        RB_transplant(T_nil,T_root, z, y);
    630 
    631        y->left= z->left;
    632 
    633        y->left->p= y;
    634 
    635        y->color= z->color;
    636 
    637     //  printf("
    NNNNNNNNNNNNNNNNNNNNNNNNNN
    ");
    638 
    639     }
    640 
    641     if(y_original_color== 'B')
    642 
    643        RB_delete_fixup(T_nil,T_root, x);
    644 
    645     else{
    646 
    647        inttree_height;
    648 
    649        tree_height= get_tree_height(T_root);
    650 
    651        print_tree(T_root,tree_height);
    652 
    653     }
    654 
    655 }
    656 
    657  
    658 
    659 struct node * tree_minimum(tree_pointer T_nil,tree_pointer x){
    660 
    661     while(x->left!= T_nil)
    662 
    663        x =x->left;
    664 
    665     return x;
    666 
    667 }
    668 
    669  
    670 
    671 void RB_delete_fixup(tree_pointer T_nil, tree_pointerT_root, tree_pointer x){  
    672 
    673     tree_pointerw = NULL;
    674 
    675     w = (structnode *)malloc(sizeof(struct node));
    676 
    677  
    678 
    679     while(x != T_root&& x->color == 'B'){
    680 
    681        if(x ==x->p->left){
    682 
    683            w =x->p->right;
    684 
    685            if(w->color== 'R'){
    686 
    687               w->color= 'B';
    688 
    689               x->p->color= 'R';
    690 
    691               left_rotate(T_nil,T_root, x->p);
    692 
    693               w =x->p->right;
    694 
    695            }
    696 
    697            if(w->left->color== 'B' && w->right->color == 'B'){
    698 
    699               w->color= 'R';
    700 
    701               x =x->p;
    702 
    703            }
    704 
    705            elseif(w->right->color == 'B'){
    706 
    707               w->left->color= 'B';
    708 
    709               w->color= 'R';
    710 
    711               right_rotate(T_nil,T_root, w);
    712 
    713               w =x->p->right;
    714 
    715            }
    716 
    717            else{
    718 
    719               w->color= x->p->color;
    720 
    721               x->p->color= 'B';
    722 
    723               w->right->color= 'B';
    724 
    725               left_rotate(T_nil,T_root, x->p);
    726 
    727               x =T_root;
    728 
    729            }
    730 
    731       
    732 
    733        }
    734 
    735        else{
    736 
    737            w =x->p->left;
    738 
    739            if(w->color== 'R'){
    740 
    741               w->color= 'B';
    742 
    743               x->p->color= 'R';
    744 
    745               right_rotate(T_nil,T_root, x->p);
    746 
    747               w =x->p->left;
    748 
    749            }
    750 
    751            if(w->right->color== 'B' && w->left->color == 'B'){
    752 
    753               w->color = 'R';
    754 
    755               x = x->p;
    756 
    757            }
    758 
    759            elseif(w->left->color == 'B'){
    760 
    761               w->right->color= 'B';
    762 
    763               w->color= 'R';
    764 
    765               left_rotate(T_nil,T_root, w);
    766 
    767               w =x->p->left;
    768 
    769            }
    770 
    771            else{
    772 
    773               w->color= x->p->color;
    774 
    775               x->p->color= 'B';
    776 
    777               w->left->color= 'B';
    778 
    779               right_rotate(T_nil,T_root, x->p);
    780 
    781               x =T_root;
    782 
    783            }
    784 
    785        }
    786 
    787     }
    788 
    789     x->color ='B';
    790 
    791  
    792 
    793     inttree_height;
    794 
    795     tree_height =get_tree_height(T_root);
    796 
    797     print_tree(T_root,tree_height);
    798 
    799 }
    View Code
    说明:所有内容仅做学习记录
  • 相关阅读:
    一个生成随机颜色的js函数
    实战vue代码
    vue练习用免费开源api大全
    vue-resource插件使用
    专题 查找与排序的Java代码实现(一)
    十字链表的画法
    20162322 朱娅霖 作业009 堆和优先队列
    20162322 朱娅霖 作业008 二叉查找树
    20162322 朱娅霖 实验报告二 树
    20162322 朱娅霖 作业007 树
  • 原文地址:https://www.cnblogs.com/jayinnn/p/9559392.html
Copyright © 2011-2022 走看看