【C++】 红黑树实现

【本文原创于Paul的博客园技术博客。】

【本文欢迎转载,转载请以链接形式注明出处。】

【本博客所有文章都经博主精心整理,请尊重我的劳动成果。】

【C++】红黑树实现

红黑树的定义:

一棵二叉查找树如果满足下面的红黑性质,则为一棵红黑树。

1)每个节点或是红的,或是黑的。

2)根节点是黑的。

3)每个叶节点(NIL)是黑节点。

4)如果一个节点是红的,则它的两个儿子都是黑的。

5)对每个节点,从该节点到其子孙节点的所有路径上包含相同节点数目的黑节点。

关于更多红黑树的知识请参见百度百科:红黑树

C++:BRTreeNode.h


 1 #ifndef BRTREENODE_H_INCLUDED
2 #define BRTREENODE_H_INCLUDED
3 #include<iostream>
4 using namespace std;
5 class BRTree;
6 class BRTreeNode
7 {
8 private:
9 friend class BRTree;
10 int key;
11 bool color;
12 BRTreeNode* left;
13 BRTreeNode* right;
14 BRTreeNode* parent;
15 public:
16 BRTreeNode():key(-1),color(0),left(NULL),right(NULL),parent(NULL){}
17 BRTreeNode(BRTreeNode* node):key(node->key),color(node->color),left(node->left),right(node->right),parent(node->parent)
18 {}
19 BRTreeNode(int num,bool flag):key(num),color(flag),left(NULL),right(NULL),parent(NULL){}
20 ~BRTreeNode()
21 {
22
23 }
24 int Getkey()
25 {
26 return key;
27 }
28 bool Getcolor()
29 {
30 return this->color;
31 }
32 BRTreeNode* GetLeft()
33 {
34 return this->left;
35 }
36 BRTreeNode* Getright()
37 {
38 return this->right;
39 }
40 BRTreeNode* Getparent()
41 {
42 return this->parent;
43 }
44 void Inorder()
45 {
46 if(this!=NULL)
47 {
48 this->left->Inorder();
49 cout<<this->key<<" ";
50 this->right->Inorder();
51 }
52 }
53 void Preorder()
54 {
55 if(this!=NULL)
56 {
57 cout<<this->key<<" ";
58 this->left->Preorder();
59 this->right->Preorder();
60 }
61 }
62 void Postorder()
63 {
64 if(this!=NULL)
65 {
66 this->left->Postorder();
67 this->right->Postorder();
68 cout<<this->key<<" ";
69 }
70 }
71
72 void MakeEmpty()
73 {
74 if(this!=NULL)
75 {
76 this->left->MakeEmpty();
77 this->right->MakeEmpty();
78 delete this;
79 }
80 }
81 int GetHeight()
82 {
83 int L,R;
84 if(this==NULL)
85 {
86 return 0;
87 }
88 L=this->left->GetHeight();
89 R=this->right->GetHeight();
90 return 1+(L>R? L:R);
91 }
92 };
93
94
95 #endif // BRTREENODE_H_INCLUDED

BRTree.h


  1 #ifndef BRTREE_H_INCLUDED
2 #define BRTREE_H_INCLUDED
3 #define maxSize 30
4 #define maxWidth 30
5 #include"BRTreeNode.h"
6 class BRTree
7 {
8 private:
9 BRTreeNode* root;
10 BRTreeNode* nil;
11 public:
12 BRTree():nil(new BRTreeNode())
13 {
14 nil->color=0;
15 nil->key=-1;
16 nil->left=nil->right=nil->parent=NULL;
17 root=nil;
18 }
19 ~BRTree()
20 {
21 MakeEmpty(root);
22 delete nil;
23 }
24 //清空以node为根节点的树
25 void MakeEmpty(BRTreeNode*node)
26 {
27 if(node!=nil)
28 {
29 MakeEmpty(node->left);
30 MakeEmpty(node->right);
31 delete node;
32 }
33 }
34 int Getkey(BRTreeNode* node)
35 {
36 return node->Getkey();
37 }
38 bool Getcolor(BRTreeNode* node)
39 {
40 return node->Getcolor();
41 }
42 BRTreeNode* Getroot()
43 {
44 return root;
45 }
46 BRTreeNode* GetParent(BRTreeNode*node)
47 {
48 return node->parent;
49 }
50 int GetHeight(BRTreeNode* node)
51 {
52 int L,R;
53 if(node==nil)
54 return 0;
55 L=GetHeight(node->left);
56 R=GetHeight(node->right);
57 return 1+(L>R? L:R);
58 }
59 int GetBlackHeight(BRTreeNode* node)
60 {
61 int L,R;
62 if(node==nil) return 0;
63 L=GetHeight(node->left);
64 R=GetHeight(node->right);
65 if(node->Getcolor()) return(L>R? L:R);
66 else return 1+(L>R? L:R);
67 }
68 void Inorder(BRTreeNode*node)
69 {
70 if(node!=nil)
71 {
72 Inorder(node->left);
73 cout<<node->key<<" ";
74 Inorder(node->right);
75 }
76 }
77 void Preorder(BRTreeNode*node)
78 {
79 if(node!=nil)
80 {
81 cout<<node->key<<" ";
82 Preorder(node->left);
83 Preorder(node->right);
84 }
85 }
86 void Posetorder(BRTreeNode*node)
87 {
88 if(node!=nil)
89 {
90 Posetorder(node->left);
91 Posetorder(node->right);
92 cout<<node->key<<" ";
93 }
94 }
95 //层次法打印树
96 void DispTree(BRTreeNode*BT)
97 {
98 BRTreeNode stack[maxSize],p;
99 int level[maxSize][2],top,n,i,width=4;
100 if(BT!=NULL)
101 {
102 cout<<"Display a tree by hollow means."<<endl;
103 top=1;
104 stack[top]=BT;//push root point to stack.
105 level[top][0]=width;
106 while(top>0)
107 {
108 p=stack[top];
109 n=level[top][0];
110 for(i=1;i<=n;i++)
111 cout<<" ";
112 //输出信息
113 if(p.key==0)
114 {
115 cout<<")";
116 }
117 else{
118 if(p.key==-1) cout<<"Nil";
119 else if(p.left&&p.right) cout<<"("<<p.key;
120 else cout<<p.key;
121 if(p.Getcolor()) cout<<"R,";
122 else cout<<"B,";
123 }
124 for(i=n+1;i<maxWidth;i+=2)
125 cout<<"--";
126 cout<<endl;
127 top--;
128 if(p.right!=NULL)
129 {
130 //插入一个括号节点,key值为0
131 top++;
132 BRTreeNode* tmp=new BRTreeNode();
133 tmp->key=0;
134 stack[top]=tmp;
135 level[top][0]=n+width;
136 level[top][1]=2;
137 top++;
138 stack[top]=p.right;
139 level[top][0]=n+width;
140 level[top][1]=2;
141
142 }
143 if(p.left!=NULL)
144 {
145 top++;
146 stack[top]=p.left;
147 level[top][0]=n+width;
148 level[top][1]=1;
149 }
150 }
151 }
152 }
153 //左旋节点node
154 bool LeftRotate(BRTreeNode* node)
155 {
156 BRTreeNode*y;
157 if(node->right==nil)
158 {
159 cout<<"can‘t left rotate!"<<endl;
160 return 0;
161 }
162 y=node->right;
163 node->right=y->left;
164 if(y->left!=nil)
165 {
166 y->left->parent=node;
167 }
168 y->parent=node->parent;
169 if(node->parent==nil)
170 {
171 root=y;
172 }
173 else if(node->parent->left==node)
174 {
175 node->parent->left=y;
176 }
177 else
178 {
179 node->parent->right=y;
180 }
181 y->left=node;
182 node->parent=y;
183 return 1;
184 }
185 //右旋节点
186 bool RightRotate(BRTreeNode* node)
187 {
188 if(node->left==nil)
189 {
190 cout<<"can‘t rightrotate!"<<endl;
191 return 0;
192 }
193 BRTreeNode* x;
194 x=node->left;
195 node->left=x->right;
196 if(x->right!=nil)
197 {
198 x->right->parent=node;
199 }
200 x->parent=node->parent;
201 if(node->parent==nil)
202 {
203 root=x;
204 }
205 else if(node->parent->left==node)
206 {
207 node->parent->left=x;
208 }
209 else
210 {
211 node->parent->right=x;
212 }
213 node->parent=x;
214 x->right=node;
215 return 1;
216 }
217 void Insert(int num)
218 {
219 BRTreeNode* node=new BRTreeNode(num,1);
220 node->left=nil;
221 node->right=nil;
222 node->parent=nil;
223 BRTreeNode* p=root,*q=nil;
224 if(root==nil)
225 {
226 node->color=0;
227 root=node;
228 root->left=root->right=root->parent=nil;
229 return ;
230 }
231 while(p!=nil)
232 {
233 if(p->key==num)
234 {
235 cout<<num<<" has exist!"<<endl;
236 return ;
237 }
238 else if(p->key>num)
239 {
240 q=p;
241 p=p->left;
242 }
243 else
244 {
245 q=p;
246 p=p->right;
247 }
248 }
249 if(q->key>num)
250 {
251 q->left=node;
252 node->parent=q;
253 }
254 else
255 {
256 q->right=node;
257 node->parent=q;
258 }
259 RBInsertAdjust(node);
260 }
261 void RBInsertAdjust(BRTreeNode* node)
262 {
263 BRTreeNode* y;
264 while(node->parent->color==1)
265 {
266 if(node->parent==node->parent->parent->left)
267 {
268 y=node->parent->parent->right;
269 if(y->color==1)
270 {
271 node->parent->color=0;
272 y->color=0;
273 y->parent->color=1;
274 node=node->parent->parent;
275 }
276 //此时y的颜色是黑色
277 else
278 {
279 //第二种情况
280 if(node==node->parent->right)
281 {
282 node=node->parent;
283 LeftRotate(node);
284 }
285 //第三种情况
286 node->parent->color=0;
287 node->parent->parent->color=1;
288 RightRotate(node->parent->parent);
289 }
290 }
291 else
292 {
293 y=node->parent->parent->left;
294 if(y->color==1)
295 {
296 node->parent->color=0;
297 y->color=0;
298 y->parent->color=1;
299 node=node->parent->parent;
300 }
301 else
302 {
303 if(node==node->parent->left)
304 {
305 node=node->parent;
306 RightRotate(node);
307 }
308 node->parent->color=0;
309 node->parent->parent->color=1;
310 LeftRotate(node->parent->parent);
311 }
312 }
313 }
314 root->color=0;
315 }
316 BRTreeNode* Search(int num)
317 {
318 BRTreeNode* p=root;
319 while(p!=nil)
320 {
321 if(p->key==num)
322 {
323 return p;
324 }
325 else if(p->key>num)
326 {
327 p=p->left;
328 }
329 else
330 {
331 p=p->right;
332 }
333 }
334 cout<<"there is no "<<num<<" in this tree!"<<endl;
335 return nil;
336 }
337 //获取以node节点为根节点的树的最小元素,并返回该最小值
338 int Minnum(BRTreeNode*node)
339 {
340 BRTreeNode*p=node;
341 while(p->left!=nil)
342 {
343 p=p->left;
344 }
345 return p->key;
346 }
347 //获取以node节点为根节点的树的最da元素,并返回该最da值
348 int Maxnum(BRTreeNode*node)
349 {
350 BRTreeNode*p=node;
351 while(p->right!=nil)
352 {
353 p=p->right;
354 }
355 return p->key;
356 }
357 //获取以node节点为根节点的树的最小元素,并返回该节点
358 BRTreeNode* MinNum(BRTreeNode*node)
359 {
360 BRTreeNode*p=node;
361 while(p->left!=nil)
362 {
363 p=p->left;
364 }
365 return p;
366 }
367 //获取以node节点为根节点的树的最大元素
368 BRTreeNode* MaxNum(BRTreeNode*node)
369 {
370 BRTreeNode*p=node;
371 while(p->right!=nil)
372 {
373 p=p->right;
374 }
375 return p;
376 }
377 BRTreeNode*InorderSuccessor(BRTreeNode*node)
378 {
379 if(node->right!=nil)
380 {
381 return MinNum(node->right);
382 }
383 else
384 {
385 BRTreeNode*p=GetParent(node);
386 while(p&&node==p->right)
387 {
388 node=p;
389 p=GetParent(node);
390 }
391 return p;
392 }
393 }
394 //中序遍历的前趋
395 BRTreeNode*InordePredecessor(BRTreeNode*node)
396 {
397 if(node->left!=nil)
398 {
399 return MaxNum(node->left);
400 }
401 else
402 {
403 BRTreeNode*p=GetParent(node);
404 while(p&&node==p->left)
405 {
406 node=p;
407 p=GetParent(node);
408 }
409 return p;
410 }
411 }
412 bool Delete(int num)
413 {
414 BRTreeNode*z,*y,*x;
415 //寻找key值为num的节点p
416 z=Search(num);
417 //如果没有该节点则返回0
418 if(z==nil)
419 {
420 return 0;
421 }
422 if(z->left==nil||z->right==nil)
423 {
424 y=z;
425 }
426 else
427 y=InorderSuccessor(z);
428 if(y->left!=nil)
429 x=y->left;
430 else
431 x=y->right;
432 x->parent=y->parent;
433 if(x->parent==nil)
434 root=x;
435 else if(y=y->parent->left)
436 y->parent->left=x;
437 else
438 y->parent->right=x;
439 if(y!=z)
440 {
441 z->key=y->key;
442 }
443 if(y->color==0)
444 {
445 RBTreeFixup(x);
446 }
447 return 1;
448 }
449 void RBTreeFixup(BRTreeNode* x)
450 {
451 BRTreeNode*w;
452 while(x!=root&&x->color==0)
453 {
454 if(x==x->parent->left)
455 {
456 w=x->parent->right;
457 if(w->color==1)
458 {
459 w->color=0;
460 x->parent->color=1;
461 LeftRotate(x->parent);
462 w=x->parent->right;
463 }
464 if(w->left->color==0&&w->right->color==0)
465 {
466 w->color=1;
467 x=x->parent;
468 }
469 else
470 {
471 if(w->right->color==0)
472 {
473 w->color=1;
474 RightRotate(w);
475 w=x->parent->right;
476 }
477 w->color=x->parent->color;
478 x->parent->color=0;
479 w->right->color=0;
480 LeftRotate(x->parent);
481 x=root;
482 }
483 }
484 else
485 {
486 w=x->parent->left;
487 if(w->color==1)
488 {
489 w->color=0;
490 x->parent->color=1;
491 RightRotate(x->parent);
492 w=x->parent->left;
493 }
494 if(w->right->color==0&&w->left->color==0)
495 {
496 w->color=1;
497 x=x->parent;
498 }
499 else
500 {
501 if(w->left->color==0)
502 {
503 w->color=1;
504 LeftRotate(w);
505 w=x->parent->left;
506 }
507 w->color=x->parent->color;
508 x->parent->color=0;
509 w->left->color=0;
510 RightRotate(x->parent);
511 x=root;
512 }
513 }
514 }
515 x->color=0;
516 }
517 };
518
519 #endif // BRTREE_H_INCLUDED

【C++】 红黑树实现

时间: 2024-10-07 07:48:47

【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树的搜索性