• 红黑树C++实现


    复制代码
      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)&&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_ */
    复制代码
  • 相关阅读:
    Integer中计算int位数的方法
    Spark学习---常见的RDD转和行动操作
    Spark学习---RDD编程
    《教父》中的经典台词以及英文原版
    关于MATSIM中,如何关闭自动加载dtd的问题
    源发行版8需要目标发行版1.8
    关于Mysql中GROUP_CONCAT函数返回值长度的坑
    【转】通过xml处理sql语句时对小于号与大于号的处理转换
    XmlDocument根据节点的属性值获取节点
    【转】使用SevenZipSharp压缩、解压文件
  • 原文地址:https://www.cnblogs.com/zhangyuhang3/p/6909892.html
Copyright © 2020-2023  润新知