红黑树C++实现

来源:互联网 发布:网络篮球游戏 编辑:程序博客网 时间:2024/06/16 21:44
复制代码
  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                 else189 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                 }else230 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)&&current_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_ */
复制代码
原创粉丝点击