红黑树删除操作
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 }
以上是关于红黑树删除操作的主要内容,如果未能解决你的问题,请参考以下文章