红黑树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_ */

时间: 2025-01-02 16:59:52

红黑树C++实现的相关文章

B树、B+树、红黑树、AVL树比较

B树是为了提高磁盘或外部存储设备查找效率而产生的一种多路平衡查找树. B+树为B树的变形结构,用于大多数数据库或文件系统的存储而设计. B树相对于红黑树的区别 在大规模数据存储的时候,红黑树往往出现由于树的深度过大而造成磁盘IO读写过于频繁,进而导致效率低下的情况.为什么会出现这样的情况,我们知道要获取磁盘上数据,必须先通过磁盘移动臂移动到数据所在的柱面,然后找到指定盘面,接着旋转盘面找到数据所在的磁道,最后对数据进行读写.磁盘IO代价主要花费在查找所需的柱面上,树的深度过大会造成磁盘IO频繁读

红黑树之删除节点

红黑树之删除节点 上一篇文章中讲了如何向红黑树中添加节点,也顺便创建了一棵红黑树.今天写写怎样从红黑树中删除节点. 相比于添加节点,删除节点要复杂的多.不过我们慢慢梳理,还是能够弄明白的. 回顾一下红黑树的性质 红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色.在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求: 节点是红色或黑色. 根节点是黑色. 每个叶节点(这里的叶节点是指NULL节点,在<算法导论>中这个节点叫哨兵节点,除了颜色属性外,其他属性值都为任

数据结构与算法-红黑树

前言 红黑树是工程中最常用到的一种自平衡二叉排序树,其和AVL树类似,都是在进行插入.删除时通过一定的调整操作来维持相对稳定的树高,从而获得较好的查询性能. 性质 1. 节点是红色或黑色. 2. 根节点是黑色. 3 每个叶节点(null节点)是黑色的. 4 每个红色节点的两个子节点都是黑色.(从每个叶子到根的所有路径上不能有两个连续的红色节点) 5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点. 维护红黑树形状(树高)的,主要就是4.5两条性质,性质4决定了最长的路径莫过于红黑间隔

数据结构学习笔记-排序/队/栈/链/堆/查找树/红黑树

排序: 插入排序:每次从剩余数据中选取一个最小的,插入已经排序完成的序列中 合并排序:将数据分成左右两组分别排序,然后合并,对每组数据的排序递归处理. 冒泡排序:重复交换两个相邻元素,从a[1]开始向a[0]方向冒泡,然后a[2]...当a[i]无法继续往前挤的时候说明前面的更小了,而且越往前越小(挤得越往前) 堆排序:构造最大堆,每次取走根结点(自然是最大的),再调用MAX-HEAPIFY算法(见后文的堆)恢复最大堆的性质,重复取走根结点 快速排序(对A[r]-A[n]进行排序): 1.从序列

红黑树与AVL(平衡二叉树)的区别

关于红黑树和AVL树,来自网络: 1 好处 及 用途 红黑树 并不追求"完全平衡 "--它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能. 红黑树能够以 O(log2  n)  的时间复杂度进行搜索.插入.删除操作.此外,由于它的设计,任何不平衡都会在三次旋转之内解决.当然,还有一些更好的,但实现起来更复杂的数据结构 能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较"便宜"的解决方案.红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高

数据结构-红黑树

转自:http://dongxicheng.org/structure/red-black-tree/ 1. 简介 红黑树是一种自平衡二叉查找树.它的统计性能要好于平衡二叉树(AVL树),因此,红黑树在很多地方都有应用.在C++ STL中,很多部分(目前包括set, multiset, map, multimap)应用了红黑树的变体(SGI STL中的红黑树有一些变化,这些修改提供了更好的性能,以及对set操作的支持).它是复杂的,但它的操作有着良好的最坏情况运行时间,并且在实践中是高效的: 它

红黑树

弄了很久,学习过程中觉得很难,但学完了,其实感觉也就那样,就是情况多了些. 首先是插入,插入的时候其实也就3种情况,因为只有当插入的节点的父亲是红色的时候,此时红黑树的性质遭到破坏,需要旋转,再分1.叔父节点为红,此时只要改变颜色,但祖父节点颜色的改变可能会破坏红黑树的性质,所以要node = grandparent,继续向上,叔父为黑,这时需要旋转,所以得判断,自身的位置,也就是自己和父亲分别是左孩子还是右孩子,2.如果自身是右,父亲是左,的先把自己也旋转到左,再和自己是左,父亲也是左的情况一

定时器管理:nginx的红黑树和libevent的堆

libevent 发生超时后, while循环一次从堆顶del timer——直到最新调整的最小堆顶不是超时事件为止,(实际是del event),但是会稍后把这个timeout的 event放到active 任务list里, 等待处理,event标记为timeout,等处理actvie队列时再由应用层callback函数决定怎么处理标记为timeout的事件. nginx处理超时时,直接删除红黑树中( event结构体里的 )rb node成员,同时调用应用层早已通过add timer注册好的

数据结构——红黑树

红黑树是二叉排序树的改进, 红黑树有几个特点: 1:节点只有2中颜色,红色和黑色. 2:根节点一定是黑色节点. 3:红色节点的子节点一定是黑色节点. 4:黑色高度(根节点到每个叶子节点的路径长度包含相同的黑色节点)相等. 规定的插入的节点一定是红色节点, 红黑树的插入节点后需要调整的规则,插入节点需要调整的情况有3种: 情况1:插入的节点的父节点和叔叔节点都为红色: 以上情况节点4为插入节点(当前节点),这种情况调整方式是将父节点和叔叔节点都调整为黑色节点,祖父节点调整为红色,将祖父节点变为当前

【转】B树、B-树、B+树、B*树、红黑树、 二叉排序树、trie树Double Array 字典查找树简介

B  树 即二叉搜索树: 1.所有非叶子结点至多拥有两个儿子(Left和Right): 2.所有结点存储一个关键字: 3.非叶子结点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树: 如: B树的搜索,从根结点开始,如果查询的关键字与结点的关键字相等,那么就命中:否则,如果查询关键字比结点关键字小,就进入左儿子:如果比结点关键字大,就进入右儿子:如果左儿子或右儿子的指针为空,则报告找不到相应的关键字: 如果B树的所有非叶子结点的左右子树的结点数目均保持差不多(平衡),那么B树的搜索性