紅黑樹C++實現
阿新 • • 發佈:2017-05-26
con colors end ase 復制代碼 設置 typename ucc 技術
1 /* 2 * rbtree.h 3 * 1. 每個節點是紅色或者黑色 4 * 2. 根節點是黑色 5 * 3. 每個葉子節點是黑色(該葉子節點就空的節點) 6 * 4. 如果一個節點是紅色,則它的兩個子節點是黑色的 7 * 5.對每個節點,從該節點道其他所有後代的葉子節點的簡單路徑上,均包含相同數目的黑色節點 8 * 9 */ 10 11 #ifndef SRC_RBTREE_H_ 12 #define SRC_RBTREE_H_ 13 #include<iostream> 14 #include<queue> 15 16 using namespace std; 17 enum colors{ RED,BLACK}; 18 typedef int color_type; 19 namespace red_black_tree{ 20 struct rb_tree_base{ 21 struct rb_tree_base * parent; 22 struct rb_tree_base * left; 23 struct rb_tree_base * right; 24 color_type color; 25 }; 26 27 template<class T> 28 struct rb_tree_node:public rb_tree_base{ 29 T data; 30 typedef rb_tree_node<T>* link_type; 31 }; 32 template<class Value> 33 class rb_tree{ 34 public: 35 typedef rb_tree_base* rb_ptr; 36 typedef typename rb_tree_node<Value>::link_type link_type; 37 typedef rb_tree_node<Value> tree_node; 38 private: 39 rb_ptr head; 40 private: 41 bool _right_rotate(rb_ptr root); 42 bool _left_rotate(rb_ptr root); 43 rb_ptr _get_node(const Value& e) const; 44 bool _insert_fix_up(rb_ptr current_ptr); 45 46 bool _erase_fix_up(rb_ptr current_ptr,rb_ptr parent_ptr); 47 48 void _preOrder(rb_ptr root) const; 49 50 rb_ptr _successor(rb_ptr current_ptr) const; 51 public: 52 rb_tree(); 53 ~rb_tree(); 54 bool insert(const Value &e); 55 bool empty() const; 56 bool erase(const Value &e); 57 rb_ptr find(const Value &e); 58 void levelOrder() const; 59 void preOrder() const; 60 }; 61 template<class Value> 62 rb_tree<Value>::rb_tree() { 63 head = new tree_node(); 64 head->left=head; 65 head->right=head; 66 head->parent=head; 67 68 head->color=BLACK; 69 } 70 71 template<class Value> 72 rb_tree<Value>::~rb_tree() { 73 } 74 75 template<class Value> 76 bool rb_tree<Value>::insert(const Value& e) { 77 rb_ptr insert_ptr =_get_node(e); 78 if(head->parent ==head){ 79 head->parent=insert_ptr; 80 insert_ptr->parent=head; 81 insert_ptr->color=BLACK; 82 return true; 83 } 84 rb_ptr root_ptr=head->parent; 85 rb_ptr root_remember=nullptr; 86 while(root_ptr){ 87 root_remember=root_ptr; 88 if(link_type(insert_ptr)->data<=link_type(root_ptr)->data) 89 root_ptr=root_ptr->left; 90 else 91 root_ptr=root_ptr->right; 92 } 93 insert_ptr->parent=root_remember; 94 if(link_type(insert_ptr)->data <= link_type(root_remember)->data ) 95 root_remember->left=insert_ptr; 96 else if(link_type(insert_ptr)->data >link_type( root_remember)->data) 97 root_remember->right=insert_ptr; 98 bool ret =_insert_fix_up(insert_ptr); 99 return ret; 100 } 101 template<class Value> 102 bool rb_tree<Value>::empty() const { 103 104 return head->parent==head; 105 } 106 107 template<class Value> 108 bool rb_tree<Value>::erase(const Value& e) { 109 110 rb_ptr erase_ptr = find(e); 111 112 if(!erase_ptr) 113 114 return false; 115 116 int erase_color =erase_ptr->color; 117 118 rb_ptr fix_up_ptr=nullptr; 119 120 rb_ptr fix_up_parent_ptr=nullptr; 121 122 if(erase_ptr){ 123 124 if(!erase_ptr->left&&!erase_ptr->right){//葉子節點 125 126 if(erase_ptr==erase_ptr->parent->left){ 127 128 erase_ptr->parent->left=nullptr; 129 130 fix_up_parent_ptr= erase_ptr->parent; 131 132 } 133 134 if(erase_ptr==erase_ptr->parent->right){ 135 136 erase_ptr->parent->right=nullptr; 137 138 fix_up_parent_ptr= erase_ptr->parent; 139 140 } 141 142 if(erase_ptr==head->parent){ 143 144 head->parent=head; 145 146 fix_up_parent_ptr=head; 147 148 } 149 150 erase_color =erase_ptr->color; 151 152 delete erase_ptr; 153 154 }else if(erase_ptr->right){ 155 156 rb_ptr successor_ptr =_successor(erase_ptr);//left一定為空 157 158 link_type(erase_ptr)->data=link_type(successor_ptr)->data; 159 160 if(successor_ptr==successor_ptr->parent->left) 161 162 successor_ptr->parent->left=successor_ptr->right; 163 164 if(successor_ptr==successor_ptr->parent->right) 165 166 successor_ptr->parent->right=successor_ptr->right; 167 168 if(successor_ptr->right) 169 170 successor_ptr->right->parent=successor_ptr->parent; 171 172 173 174 fix_up_ptr=successor_ptr->right; 175 176 fix_up_parent_ptr=successor_ptr->parent; 177 178 erase_color=successor_ptr->color; 179 180 delete successor_ptr; 181 182 }else{//直接用左子樹代替,或者找到後繼節點代替也行,但比較麻煩,效果一樣。 183 184 if(erase_ptr ==erase_ptr->parent->left) 185 186 erase_ptr->parent->left=erase_ptr->left; 187 188 else 189 190 erase_ptr->parent->right=erase_ptr->left; 191 192 erase_ptr->left->parent=erase_ptr->parent; 193 194 fix_up_ptr=erase_ptr->left; 195 196 fix_up_parent_ptr=erase_ptr->parent; 197 198 erase_color=erase_ptr->color; 199 200 delete erase_ptr; 201 202 } 203 204 if(erase_color==BLACK) 205 206 return _erase_fix_up(fix_up_ptr,fix_up_parent_ptr); 207 208 } 209 return false; 210 } 211 212 template<class Value> 213 typename rb_tree<Value>::rb_ptr rb_tree<Value>::find(const Value& e) { 214 215 rb_ptr root=head->parent; 216 217 if(head->parent !=head){ 218 219 while(root){ 220 221 if(link_type(root)->data == e) 222 223 return root; 224 225 else if( e<=link_type(root)->data){ 226 227 root=root->left; 228 229 }else 230 231 root=root->right; 232 233 } 234 235 } 236 return nullptr; 237 } 238 /** 239 * current_ptr節點的祖父節點一定是黑色,因為它的父節點是紅色的,所以性質4只在插入節點和該父節點被破壞 240 * 情況1:叔節節點uncle_ptr是紅色; 241 * 1)父節點parent_ptr和叔節點uncle_ptr的顏色改為黑色,祖父節點grandfather_ptr的顏色改為紅色 242 * 2)把current_ptr節點設置為grandfather,因為只有祖父節點和祖父節點的父節點之間會違法性質。 243 244 * 情況2:叔父節點uncle_ptr是黑色,或者unclue_ptr為空; 245 246 * 1)根據根據當前節點的位置,把當前節點current_ptr設置為parent_ptr,對其左旋或右旋。 247 248 * 情況3:叔父節點存在或者叔父節點顏色為黑色,且父右兒右關系(或父左兒左) 249 250 1)把父節點顏色設為黑色,把祖父顏色設為紅色 251 252 2)對祖父節點進行左旋(或右旋) 253 * 254 */ 255 template<class Value> 256 bool rb_tree<Value>:: _insert_fix_up(rb_ptr current_ptr){ 257 while(current_ptr->parent->color ==RED){ 258 259 rb_ptr parent_ptr =current_ptr->parent; 260 rb_ptr grandfather_ptr=parent_ptr->parent; 261 if(parent_ptr ==grandfather_ptr->left){ 262 rb_ptr uncle_ptr=parent_ptr->parent->right; 263 if(uncle_ptr && uncle_ptr->color==RED){ 264 parent_ptr->color=BLACK; 265 uncle_ptr->color=BLACK; 266 grandfather_ptr->color=RED; 267 current_ptr=grandfather_ptr; 268 }else if(current_ptr ==parent_ptr->right){ 269 current_ptr=parent_ptr; 270 _left_rotate(current_ptr); 271 }else{ 272 273 current_ptr->parent->color=BLACK; 274 current_ptr->parent->parent->color=RED; 275 _right_rotate(current_ptr->parent->parent); 276 277 } 278 }else{ 279 rb_ptr uncle_ptr=parent_ptr->parent->left; 280 if(uncle_ptr && uncle_ptr->color==RED){ 281 parent_ptr->color=BLACK; 282 uncle_ptr->color=BLACK; 283 grandfather_ptr->color=RED; 284 current_ptr=grandfather_ptr; 285 }else if(current_ptr ==parent_ptr->left){//uncle_ptr->color 是BLACK,或者uncle_ptr為空 286 current_ptr=parent_ptr; 287 _right_rotate(current_ptr);//其實就是轉換為父右兒右的情況 288 }else{//父右兒右 289 290 current_ptr->parent->color=BLACK; 291 current_ptr->parent->parent->color=RED; 292 _left_rotate(current_ptr->parent->parent); 293 294 } 295 } 296 } 297 head->parent->color=BLACK; 298 return true; 299 } 300 301 template<class Value> 302 303 bool rb_tree<Value>::_erase_fix_up(rb_ptr current_ptr,rb_ptr parent_ptr){ 304 305 while((!current_ptr||current_ptr->color==BLACK)&¤t_ptr!=head->parent){ 306 307 if(parent_ptr->left ==current_ptr){ 308 309 rb_ptr brother_ptr = parent_ptr->right; 310 311 if(brother_ptr->color ==RED){ 312 313 parent_ptr->color=RED; 314 315 brother_ptr->color=BLACK; 316 317 _left_rotate(brother_ptr); 318 319 brother_ptr=current_ptr->parent->right; 320 321 } 322 323 if(brother_ptr->color==BLACK && 324 325 (!brother_ptr->left ||brother_ptr->left->color ==BLACK)&& 326 327 (!brother_ptr->right || brother_ptr->right->color ==BLACK)){ 328 329 brother_ptr->color=RED; 330 331 current_ptr=parent_ptr; 332 333 parent_ptr=current_ptr->parent; 334 335 }else { 336 337 if(brother_ptr->color==BLACK && 338 339 (!brother_ptr->right||brother_ptr->right->color==BLACK)){//右侄黑,左侄紅 340 341 342 343 brother_ptr->left->color=BLACK; 344 345 brother_ptr->color=RED; 346 347 _right_rotate(brother_ptr); 348 349 brother_ptr=parent_ptr->right; 350 351 }//右侄紅色 352 353 brother_ptr->color=parent_ptr->color; 354 355 parent_ptr->color=BLACK; 356 357 if(brother_ptr->right) 358 359 brother_ptr->right->color=BLACK; 360 361 _left_rotate(parent_ptr); 362 363 current_ptr=head->parent; 364 365 } 366 367 }else{ 368 369 rb_ptr brother_ptr = parent_ptr->left; 370 371 if(brother_ptr->color ==RED){ 372 373 parent_ptr->color=RED; 374 375 brother_ptr->color=BLACK; 376 377 _right_rotate(brother_ptr); 378 379 brother_ptr=current_ptr->parent->left; 380 381 } 382 383 if(brother_ptr->color==BLACK && 384 385 (!brother_ptr->left ||brother_ptr->left->color ==BLACK)&& 386 387 (!brother_ptr->right || brother_ptr->right->color ==BLACK)){ 388 389 brother_ptr->color=RED; 390 391 current_ptr=parent_ptr; 392 393 parent_ptr=current_ptr->parent; 394 395 }else { 396 397 if(brother_ptr->color==BLACK && 398 399 (!brother_ptr->right||brother_ptr->right->color==BLACK)){//右侄黑,左侄紅 400 401 brother_ptr->left->color=BLACK; 402 403 brother_ptr->color=RED; 404 405 _left_rotate(brother_ptr); 406 407 brother_ptr=parent_ptr->left; 408 409 }//右侄紅色 410 411 brother_ptr->color=parent_ptr->color; 412 413 parent_ptr->color=BLACK; 414 415 if(brother_ptr->left) 416 417 brother_ptr->left->color=BLACK; 418 419 _right_rotate(parent_ptr); 420 421 current_ptr=head->parent; 422 423 } 424 425 } 426 427 } 428 429 if (current_ptr) 430 431 current_ptr->color=BLACK; 432 433 return true; 434 435 } 436 437 template<class Value> 438 439 typename rb_tree<Value>::rb_ptr rb_tree<Value>::_successor(rb_ptr current_ptr) const{ 440 441 rb_ptr right_child_ptr = current_ptr->right; 442 443 if(right_child_ptr){ 444 445 rb_ptr left_ptr =right_child_ptr->left; 446 447 rb_ptr left_remember_ptr; 448 449 if(left_ptr){ 450 451 while(left_ptr){ 452 453 left_remember_ptr =left_ptr; 454 455 left_ptr=left_ptr->left; 456 457 } 458 459 return left_remember_ptr; 460 461 } 462 463 return right_child_ptr; 464 465 466 467 }else{ 468 469 rb_ptr parent_ptr=current_ptr->parent; 470 471 while(current_ptr ==parent_ptr->right){ 472 473 current_ptr=parent_ptr; 474 475 parent_ptr=parent_ptr->parent; 476 477 } 478 479 return parent_ptr; 480 481 } 482 483 return nullptr; 484 485 } 486 template<class Value> 487 typename rb_tree<Value>::rb_ptr rb_tree<Value>::_get_node(const Value& e) const { 488 rb_ptr insert_ptr = new tree_node(); 489 link_type(insert_ptr)->data=e; 490 insert_ptr->parent=nullptr; 491 insert_ptr->left=nullptr; 492 insert_ptr->right=nullptr; 493 insert_ptr->color=RED; 494 return insert_ptr; 495 } 496 template<class Value> 497 bool rb_tree<Value>::_right_rotate(rb_ptr root){ 498 if(root->left!=nullptr){ 499 rb_ptr left_child_ptr=root->left; 500 501 root->left=left_child_ptr->right; 502 if(left_child_ptr->right !=nullptr) 503 left_child_ptr->right->parent=root; 504 505 left_child_ptr->right=root; 506 left_child_ptr->parent=root->parent; 507 if(root->parent->left ==root) 508 root->parent->left=left_child_ptr; 509 else if(root->parent->right==root) 510 root->parent->right=left_child_ptr; 511 512 if(root->parent==head){ 513 514 root->parent->parent=left_child_ptr; 515 516 } 517 518 root->parent=left_child_ptr; 519 return true; 520 } 521 return false; 522 } 523 template<class Value> 524 bool rb_tree< Value >::_left_rotate(rb_ptr root){ 525 if(root->right!=nullptr){ 526 rb_ptr right_child_ptr=root->right; 527 528 root->right=right_child_ptr->left; 529 if(right_child_ptr->left != nullptr) 530 right_child_ptr->left->parent=root; 531 532 right_child_ptr->left=root; 533 right_child_ptr->parent=root->parent; 534 if(root->parent->left ==root) 535 root->parent->left=right_child_ptr; 536 else if(root->parent->right ==root) 537 root->parent->right=right_child_ptr; 538 539 if(root->parent==head){ 540 541 root->parent->parent=right_child_ptr; 542 543 } 544 root->parent=right_child_ptr; 545 546 return true; 547 } 548 return false; 549 } 550 template<class Value> 551 void rb_tree<Value>::levelOrder() const { 552 rb_ptr root =head->parent; 553 queue<rb_ptr> q; 554 if(head->parent !=head){ 555 q.push(root); 556 while(!q.empty()){ 557 rb_ptr visit_ptr = q.front(); 558 cout<<"data: "<<link_type(visit_ptr)->data<<" color: "<<((visit_ptr->color==0)?"RED":"BLACK")<<endl; 559 if(visit_ptr->left) 560 q.push(visit_ptr->left); 561 if(visit_ptr->right) 562 q.push(visit_ptr->right); 563 q.pop(); 564 } 565 } 566 } 567 template<class Value> 568 void rb_tree<Value>:: _preOrder(rb_ptr root) const{ 569 if(root){ 570 cout<<"data: "<<link_type(root)->data<<" color: " 571 572 <<((root->color==0)?"RED":"BLACK")<<endl; 573 _preOrder(root->left); 574 _preOrder(root->right); 575 } 576 } 577 template<class Value> 578 void rb_tree<Value>:: preOrder() const{ 579 _preOrder(head->parent); 580 } 581 } 582 583 584 //#include "rbtree.cpp" 585 #endif /* SRC_RBTREE_H_ */
紅黑樹C++實現