红黑树删除操作

Posted jayinnn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了红黑树删除操作相关的知识,希望对你有一定的参考价值。

红黑树删除操作

实验目的

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

 

实验原理

与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

 

以上是关于红黑树删除操作的主要内容,如果未能解决你的问题,请参考以下文章

红黑树详解——数据删除操作

红黑树删除操作

算法手撕红黑树(下)—— 一张流程图梳理删除操作(含实现代码)

红黑树平衡二叉查找树

红黑树平衡二叉查找树

红黑树的插入与删除