1. 程式人生 > >紅黑樹C++實現

紅黑樹C++實現

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)&&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_ */
技術分享

紅黑樹C++實現