二叉树之红黑树(RBTree)

红黑树(RB-Tree)

  引用:https://www.cnblogs.com/skywang12345/

  详解以后再补充。。。

红黑树和AVL树6层模式下的最少结点数

  通过图可以看到红黑树可以实现更少的结点,反过来说就是同样的结点数红黑树最大数高会超过AVL树

  https://www.cs.usfca.edu/~galles/visualization/Algorithms.html这个网站可以测试动态效果,下图就是截图于此

 

 

红黑树插入删除步骤

 

输出

代码

其余代码:https://github.com/Duacai/Data-Structure-and-Algorithms/tree/master/Data-Structure/Tree/RBTree

工程通过Qt Creator创建

RBTree.h

  1 #ifndef RBTREE_H
  2 #define RBTREE_H
  3 
  4 #include <iostream>
  5 #include <iomanip>
  6 #include <queue>
  7 
  8 using namespace std;
  9 
 10 namespace Viclib
 11 {
 12 
 13 enum RBTColor { RED, BLACK };
 14 
 15 template <typename T>
 16 class RBTNode
 17 {
 18 public:
 19     RBTColor mColor;
 20     T mKey;
 21     RBTNode<T>* mLeft;
 22     RBTNode<T>* mRight;
 23     RBTNode<T>* mParent;
 24 
 25     RBTNode(RBTColor color, T key, RBTNode<T>* left, RBTNode<T>* right, RBTNode<T>* parent) :
 26         mColor(color), mKey(key), mLeft(left), mRight(right), mParent(parent) {}
 27 };
 28 
 29 template <typename T>
 30 class RBTree
 31 {
 32 private:
 33     RBTNode<T>* mRoot;
 34     uint64_t mCount;
 35     uint16_t mHeight;
 36 
 37     void preOrder(RBTNode<T>* tree) const;
 38     void inOrder(RBTNode<T>* tree) const;
 39     void postOrder(RBTNode<T>* tree) const;
 40 
 41     void levelOrder(RBTNode<T>* tree) const;
 42 
 43     RBTNode<T>* search(RBTNode<T>* tree, T key) const;
 44     RBTNode<T>* iterativeSearch(RBTNode<T>* tree, T key) const;
 45 
 46     RBTNode<T>* minimum(RBTNode<T>* tree) const;
 47     RBTNode<T>* maximum(RBTNode<T>* tree) const;
 48 
 49     void lRotate(RBTNode<T>* &tree, RBTNode<T>* node) const;
 50     void rRotate(RBTNode<T>* &tree, RBTNode<T>* node) const;
 51 
 52     void insert(RBTNode<T>* &tree, RBTNode<T>* node);
 53     void insertFixUp(RBTNode<T>* &tree, RBTNode<T>* node);    // 插入修正红黑树
 54 
 55     void remove(RBTNode<T>* &tree, RBTNode<T> *del);
 56     void removeFixUp(RBTNode<T>* &tree, RBTNode<T>* del, RBTNode<T>* parent);    // 删除修正红黑树(被删除的是黑色)
 57 
 58     void printTree(RBTNode<T> const* const tree, bool firstNode) const;
 59 
 60     void destroy(RBTNode<T>* &tree);
 61     uint16_t max(uint16_t left, uint16_t right) const;
 62     uint16_t updateHeight(RBTNode<T> *node);
 63 
 64 public:
 65     RBTree();
 66     ~RBTree();
 67 
 68     void preOrder() const;
 69     void inOrder() const;
 70     void postOrder() const;
 71 
 72     void levelOrder() const;
 73 
 74     RBTNode<T>* search(T key) const;
 75     RBTNode<T>* iterativeSearch(T key) const;
 76 
 77     T const* minimum() const;
 78     T const* maximum() const;
 79 
 80     RBTNode<T>* successor(RBTNode<T>* node) const;
 81     RBTNode<T>* predecessor(RBTNode<T>* node) const;
 82 
 83     void insert(T key);
 84     bool remove(T key);
 85 
 86     void printTree() const;
 87 
 88     void destroy();
 89     uint64_t getCount() const;
 90     uint16_t getHeight(bool update = true);
 91     bool rootIsNullptr() const;
 92     T getRootKey() const;
 93     uint8_t setKeyStrLen();
 94 };
 95 
 96 template <typename T>
 97 RBTree<T>::RBTree() : mRoot(nullptr), mCount(0ull), mHeight(0)
 98 {
 99 }
100 
101 template <typename T>
102 RBTree<T>::~RBTree()
103 {
104     destroy();
105 }
106 
107 template <typename T>
108 void RBTree<T>::preOrder(RBTNode<T>* tree) const
109 {
110     if ( tree != nullptr )
111     {
112         cout << tree->mKey << " " << flush;
113         preOrder(tree->mLeft);
114         preOrder(tree->mRight);
115     }
116 }
117 
118 template <typename T>
119 void RBTree<T>::preOrder() const
120 {
121     preOrder(mRoot);
122     cout << endl;
123 }
124 
125 template <typename T>
126 void RBTree<T>::inOrder(RBTNode<T>* tree) const
127 {
128     if ( tree != nullptr )
129     {
130         inOrder(tree->mLeft);
131         cout << tree->mKey << " " << flush;
132         inOrder(tree->mRight);
133     }
134 }
135 
136 template <typename T>
137 void RBTree<T>::inOrder() const
138 {
139     inOrder(mRoot);
140     cout << endl;
141 }
142 
143 template <typename T>
144 void RBTree<T>::postOrder(RBTNode<T>* tree) const
145 {
146     if ( tree != nullptr )
147     {
148         postOrder(tree->mLeft);
149         postOrder(tree->mRight);
150         cout << tree->mKey << " " << flush;
151     }
152 }
153 
154 template <typename T>
155 void RBTree<T>::postOrder() const
156 {
157     postOrder(mRoot);
158     cout << endl;
159 }
160 
161 template <typename T>
162 void RBTree<T>::levelOrder(RBTNode<T>* tree) const
163 {
164     if ( tree != nullptr )
165     {
166         queue<RBTNode<T>*> tmp;
167         tmp.push(tree);
168 
169         while( tmp.size() > 0 )
170         {
171             RBTNode<T>* t = tmp.front();
172 
173             if ( t->mLeft != nullptr )
174                 tmp.push(t->mLeft);
175 
176             if ( t->mRight != nullptr )
177                 tmp.push(t->mRight);
178 
179             tmp.pop();
180 
181             cout << t->mKey << " " << flush;
182         }
183     }
184 }
185 
186 template <typename T>
187 void RBTree<T>::levelOrder() const
188 {
189     levelOrder(mRoot);
190     cout << endl;
191 }
192 
193 template <typename T>
194 RBTNode<T>* RBTree<T>::search(RBTNode<T>* tree, T key) const
195 {
196     if ( tree==nullptr || key==tree->mKey )
197         return tree;
198 
199     if ( key < tree->mKey )
200         return search(tree->mLeft, key);
201     else
202         return search(tree->mRight, key);
203 }
204 
205 template <typename T>
206 RBTNode<T>* RBTree<T>::search(T key) const
207 {
208     return search(mRoot, key);
209 }
210 
211 template <typename T>
212 RBTNode<T>* RBTree<T>::iterativeSearch(RBTNode<T>* tree, T key) const
213 {
214     while ( tree!=nullptr && key!=tree->mKey )
215     {
216         if ( key < tree->mKey )
217             tree = tree->mLeft;
218         else
219             tree = tree->mRight;
220     }
221 
222     return tree;
223 }
224 
225 template <typename T>
226 RBTNode<T>* RBTree<T>::iterativeSearch(T key) const
227 {
228     return iterativeSearch(mRoot, key);
229 }
230 
231 template <typename T>
232 RBTNode<T>* RBTree<T>::minimum(RBTNode<T>* tree) const
233 {
234     if ( tree == nullptr )
235         return nullptr;
236 
237     while ( tree->mLeft != nullptr )
238         tree = tree->mLeft;
239 
240     return tree;
241 }
242 
243 template <typename T>
244 T const* RBTree<T>::minimum() const
245 {
246     RBTNode<T>* ret = minimum(mRoot);
247     if ( ret != nullptr )
248         return &ret->mKey;
249 
250     return nullptr;
251 }
252 
253 template <typename T>
254 RBTNode<T>* RBTree<T>::maximum(RBTNode<T>* tree) const
255 {
256     if ( tree == nullptr )
257         return nullptr;
258 
259     while ( tree->mRight != nullptr )
260         tree = tree->mRight;
261 
262     return tree;
263 }
264 
265 template <typename T>
266 T const* RBTree<T>::maximum() const
267 {
268     RBTNode<T>* ret = maximum(mRoot);
269     if ( ret != nullptr )
270         return &ret->mKey;
271 
272     return nullptr;
273 }
274 
275 template <typename T>
276 RBTNode<T>* RBTree<T>::successor(RBTNode<T>* tree) const    // 查找tree的后继,比tree大
277 {
278     if ( tree->right != nullptr )            // 在右节点查找最小结点
279         return minimum(tree->right);
280 
281     RBTNode<T>* p = tree->parent;
282     while ( p!=nullptr && tree==p->right )    // 父节点非空且自己是右节点就继续寻找,直至自己是左结点或父节点为空
283     {
284         tree = p;
285         p = p->parent;
286     }
287 
288     return p;
289 }
290 
291 template <typename T>
292 RBTNode<T>* RBTree<T>::predecessor(RBTNode<T>* tree) const    // 查找tree的前任,比tree小
293 {
294     if ( tree->left != nullptr )            // 在左结点查找最大结点
295         return maximum(tree->left);
296 
297     RBTNode<T>* p = tree->parent;
298     while ( p!=nullptr && tree==p->left )    // 父节点非空且自己是左结点就继续寻找,直至自己是右节点或父节点为空
299     {
300         tree = p;
301         p = p->parent;
302     }
303 
304     return p;
305 }
306 
307 /*    左旋
308  *    p                     p
309  *    |                     |
310  *   old                   new
311  *   / \     --(左旋)-->    / \
312  *  a  new                old c
313  *     / \                / \
314  *    B   c              a   B
315  */
316 template <typename T>
317 void RBTree<T>::lRotate(RBTNode<T>* &tree, RBTNode<T>* node) const    // 将右边重的结点旋转至左边重
318 {                                                                    // 当前结点成为右孩子的左孩子,右孩子的左孩子成为自己的右孩子,右孩子则替换自己位置
319     RBTNode<T>* r = node->mRight;            // 新结点指向右节点
320 
321     node->mRight = r->mLeft;                    // 更新 【当前结点(旧结点)】 与 【右节点(新结点)的左孩子】 之间的关系
322     if ( r->mLeft != nullptr )
323         r->mLeft->mParent = node;
324 
325     r->mParent = node->mParent;                // 更新 父节点 和 新孩子 之间的关系
326     if ( node->mParent == nullptr )
327         tree = r;
328     else
329     {
330         if ( node == node->mParent->mLeft )        // 判断并更新父节点的新孩子
331             node->mParent->mLeft = r;
332         else
333             node->mParent->mRight = r;
334     }
335 
336     r->mLeft = node;                            // 更新 新旧结点 之间的关系
337     node->mParent = r;
338 }
339 
340 /*    右旋
341  *      p                  p
342  *      |                  |
343  *     old                new
344  *     / \   --(右旋)-->   / \
345  *   new  c              a  old
346  *   / \                    / \
347  *  a   B                  B   c
348  */
349 template <typename T>
350 void RBTree<T>::rRotate(RBTNode<T>* &tree, RBTNode<T>* node) const
351 {
352     RBTNode<T>* l = node->mLeft;
353 
354     node->mLeft = l->mRight;
355     if ( l->mRight != nullptr )
356         l->mRight->mParent = node;
357 
358     l->mParent = node->mParent;
359     if ( node->mParent == nullptr )
360         tree = l;
361     else
362     {
363         if ( node == node->mParent->mLeft )
364             node->mParent->mLeft = l;
365         else
366             node->mParent->mRight = l;
367     }
368 
369     l->mRight = node;
370     node->mParent = l;
371 }
372 
373 template <typename T>
374 void RBTree<T>::insertFixUp(RBTNode<T>* &tree, RBTNode<T>* node)    // 插入修正红黑树
375 {
376     RBTNode<T> *parent, *gparent;    // 父结点,爷爷结点
377 
378     // node有父结点且父亲是红色(R红色、B黑色、@插入结点)
379     while ( (parent = node->mParent) && (parent->mColor==RED) )
380     {
381         gparent = parent->mParent;
382 
383         if ( parent == gparent->mLeft )    // 父亲是左孩子,叔叔是右孩子
384         {
385             {    // 叔叔有效且是红色,while保证父亲也是红色
386                 RBTNode<T>* uncle = gparent->mRight;
387                 if ( uncle && uncle->mColor==RED )    // 父亲是红色,自己默认又是红色,所以需要变色
388                 {                                    // 将父亲和叔叔设为黑结点,爷爷设为红节点;
389                     uncle->mColor = BLACK;    //   B              R
390                     parent->mColor = BLACK;    // R   R        B   B
391                     gparent->mColor = RED;    // R(@)            R(@)    // 不区分自己是左孩子还是右孩子
392                     node = gparent;                    // node指向爷爷后向上再判断其它结点是否需要平衡
393                     continue;
394                 }
395             }
396             // 父亲为红色时如果叔叔不是红色,则叔叔必是黑色叶子,且父亲的子女也全是叶子;因为父亲必须有一个叶子子结点才能插入,如果叔叔不是叶子或父亲的儿子不全是叶子则无法平衡
397             {    // 叔叔为空,自己是红色父亲的右孩子,旋转成左孩子(父子身份也交换,且父子仍为红色)
398                 if ( parent->mRight == node )// 红节点的子结点如有叶子则全是叶子,否则不平衡;父亲之前没有子结点则父亲无兄弟
399                 {
400                     RBTNode<T>* tmp;
401                     lRotate(tree, parent);    // 左旋后node替换父亲,父亲则成为自己的左孩子,变成左左模式,左左都是红色
402                     tmp = parent;            // 旋转后修正父子指针位置,父子互换
403                     parent = node;            //     B        B          B
404                     node = tmp;                //    R        R(@)       R
405                 }                            //     R(@)    R          R(@)
406             }
407 
408             {    // 叔叔为空,自己是红色父亲的左孩子
409                 parent->mColor = BLACK;        //     B        R          B
410                 gparent->mColor = RED;        //    R        B        R(@)   R
411                 rRotate(tree, gparent);        // R(@)        R(@)
412             }
413         }
414         else                        // 父亲是右孩子,伯父是左孩子
415         {
416             {    // 伯父有效且是红色,while保证父亲也是红色
417                 RBTNode<T>* uncle = gparent->mLeft;
418                 if ( uncle && uncle->mColor==RED )
419                 {
420                     uncle->mColor = BLACK;    //     B            R
421                     parent->mColor = BLACK;    // R   R         B   B
422                     gparent->mColor = RED;    //       R(@)            R(@)
423                     node = gparent;
424                     continue;
425                 }
426             }
427 
428             {    // 伯父为空或为黑色,自己是红色父亲的左孩子,旋转成右孩子(父子身份也交换,且父子仍为红色)
429                 if ( parent->mLeft == node )
430                 {
431                     RBTNode<T>* tmp;
432                     rRotate(tree, parent);
433                     tmp = parent;            // B         B       B
434                     parent = node;            //  R        R(@)     R
435                     node = tmp;                // R(@)          R       R(@)
436                 }
437             }
438 
439             {    // 伯父为空或为黑色,自己是红色父亲的右孩子
440                 parent->mColor = BLACK;        // B         R            B
441                 gparent->mColor = RED;        //    R        #       R       R(@)
442                 lRotate(tree, gparent);        //     R(@)      R(@)
443             }
444         }
445     }
446 
447     tree->mColor = BLACK;    // 如果没有父节点则当前结点就是根节点;父节点为黑则这条语句无意义
448 }
449 
450 template <typename T>
451 void RBTree<T>::insert(RBTNode<T>* &tree, RBTNode<T>* node)
452 {
453     RBTNode<T>* parent = nullptr;    // 插入点的父节点
454     RBTNode<T>* root = tree;        // 辅助寻找parent
455 
456     while ( root != nullptr )        // 寻找插入点
457     {
458         parent = root;
459         if ( node->mKey < root->mKey )
460             root = root->mLeft;
461         else
462             root = root->mRight;
463     }
464 
465     node->mParent = parent;            // 设置node结点的父节点
466     if ( parent != nullptr )        // 有父节点则插入为子结点
467         if ( node->mKey < parent->mKey )
468             parent->mLeft = node;
469         else
470             parent->mRight = node;
471     else                            // 父节点为空则设为根节点
472         tree = node;
473 
474     node->mColor = RED;                // 设为红色
475     ++mCount;
476 
477     insertFixUp(tree, node);        // 只有父节点是红色才需要平衡,但是要注意根节点没有父亲且默认插入的是红色
478 }
479 
480 template <typename T>
481 void RBTree<T>::insert(T key)
482 {
483     RBTNode<T>* node = new RBTNode<T>(RED, key, nullptr, nullptr, nullptr);    // 颜色在重载版本改为红色,此处可任意填写
484 
485     insert(mRoot, node);
486 }
487 
488 template <typename T>
489 void RBTree<T>::removeFixUp(RBTNode<T>* &tree, RBTNode<T>* del_child, RBTNode<T>* del_parent)    // 删除修正红黑树(被删除的是黑色)
490 {
491     RBTNode<T>* other;    // child的兄弟(原来的叔伯)
492 
493     // del_child为假或del_child为黑结点,且del_child不是根节点(del_child如果不是根节点就绝对是nullptr)
494     while ( (!del_child || del_child->mColor==BLACK) && del_child!=tree )    // B黑,R红,p=parent,c=child,o=other,ol=other->left,or=other->right
495     {
496         if ( del_parent->mLeft == del_child )        // 如果del_child是左结点;注意替换者已经离开了,所以child和parent是父子关系
497         {                                            // 父亲绝对有两个儿子,因为del_child原先是黑色孙子,所以绝对有一个叔伯(现在是兄弟)
498             other = del_parent->mRight;
499             if ( other->mColor == RED )                                // del_child的兄弟是红节点,它的子结点必定全是黑色
500             {
501                 other->mColor = BLACK;
502                 del_parent->mColor = RED;
503                 lRotate(tree, del_parent);
504                 other = del_parent->mRight;
505             }
506 
507             if ( (!other->mLeft || other->mLeft->mColor==BLACK) &&        // del_child兄弟的左结点为假或者为黑,且右结点也为假或者为黑
508                  (!other->mRight || other->mRight->mColor==BLACK) )    // 上面if保证del_child的兄弟也是黑色
509             {
510                 other->mColor = RED;
511                 del_child = del_parent;
512                 del_parent = del_child->mParent;
513             }
514             else
515             {
516                 if ( !other->mRight || other->mRight->mColor==BLACK )        // del_child兄弟是黑色,且该兄弟孩子不全为黑
517                 {
518                     other->mLeft->mColor = BLACK;
519                     other->mColor = RED;
520                     rRotate(tree, other);
521                     other = del_parent->mRight;
522                 }
523 
524                 other->mColor = del_parent->mColor;
525                 del_parent->mColor = BLACK;
526                 other->mRight->mColor = BLACK;
527                 lRotate(tree, del_parent);
528                 del_child = tree;
529                 break;
530             }
531         }
532         else                                        // 如果del_child是右结点
533         {
534             other = del_parent->mLeft;
535             if ( other->mColor == RED )
536             {
537                 other->mColor = BLACK;
538                 del_parent->mColor = RED;
539                 rRotate(tree, del_parent);
540                 other = del_parent->mLeft;
541             }
542 
543             if ( (!other->mLeft || other->mLeft->mColor==BLACK) &&
544                  (!other->mRight || other->mRight->mColor==BLACK) )
545             {
546                 other->mColor = RED;
547                 del_child = del_parent;
548                 del_parent = del_child->mParent;
549             }
550             else
551             {
552                 if ( !other->mLeft || other->mLeft->mColor==BLACK )
553                 {
554                     other->mRight->mColor = BLACK;
555                     other->mColor = RED;
556                     lRotate(tree, other);
557                     other = del_parent->mLeft;
558                 }
559 
560                 other->mColor = del_parent->mColor;
561                 del_parent->mColor = BLACK;
562                 other->mLeft->mColor = BLACK;
563                 rRotate(tree, del_parent);
564                 del_child = tree;                    // 也可以改成 tree->color = BLACK;
565                 break;
566             }
567         }
568     }
569 
570     if ( del_child != nullptr )                    // del_child如果存在且是红色,或者是根节点
571         del_child->mColor = BLACK;
572 }
573 
574 template <typename T>
575 void RBTree<T>::remove(RBTNode<T>* &tree, RBTNode<T>* del)
576 {
577     RBTNode<T> *child, *parent;
578     RBTColor color;
579 
580     if ( del->mLeft!=nullptr && del->mRight!=nullptr )        // 如果删除结点有两个孩子,需要找一个替换者
581     {
582         RBTNode<T>* replace = del->mRight;            // 替换者指向右结点最小者;也可以指向左结点的最大者
583         while ( replace->mLeft != nullptr )
584             replace = replace->mLeft;
585 
586         if ( del->mParent != nullptr )                // 更新父结点指向替换者
587         {
588             if ( del->mParent->mLeft == del )
589                 del->mParent->mLeft = replace;
590             else
591                 del->mParent->mRight = replace;
592         }
593         else
594             tree = replace;
595 
596         child = replace->mRight;                        // 保存替换者的子结点、父结点、颜色
597         parent = replace->mParent;
598         color = replace->mColor;
599 
600         if ( del == parent )                        // 删除的是替换者的父结点(这时替换者就是del的右结点,因为替换者没有左结点,所以del的右结点最小)
601             parent = replace;
602         else
603         {
604             if ( child != nullptr )
605                 child->mParent = parent;
606             parent->mLeft = child;                    // 替换者的父亲接管替换者的儿子(此时替换者只有右儿子,因为自己是右子树的最左下者)
607 
608             replace->mRight = del->mRight;            // 更新替换者和被删除者右儿子的关系(因为替换者位于右子树)
609             del->mRight->mParent = replace;
610         }
611 
612         replace->mParent = del->mParent;                // 更新替换者的父亲、颜色、以及与被删除者左结点的关系
613         replace->mColor = del->mColor;
614         replace->mLeft = del->mLeft;
615         del->mLeft->mParent = replace;
616     }
617     else                                                    // 删除结点孩子不足两个,独子或者叶节点就是替换者
618     {
619         if ( del->mLeft != nullptr )                    // 保存替换者的子结点、父结点、颜色
620             child = del->mLeft;
621         else
622             child = del->mRight;
623         parent = del->mParent;
624         color = del->mColor;
625 
626         if ( child != nullptr )                        // 更新 '被删除结点的父节点' 和 '被删除结点的子结点' 的关系
627             child->mParent = parent;                    // 父亲(也就是被删除结点)被删除,所以爷爷直接和唯一一个孙子互相更新关系即可
628         if ( parent != nullptr )
629         {
630             if ( parent->mLeft == del )
631                 parent->mLeft = child;
632             else
633                 parent->mRight = child;
634         }
635         else
636             tree = child;
637     }
638 
639     --mCount;                                    // 结点计数减一
640 
641     if ( color == BLACK )                        // 如果替换者或被删除者是黑色需要重新平衡(被删除者有两个儿子则是替换者),因为删除了一个黑结点
642         removeFixUp(tree, child, parent);        // child如果不是根节点或红色节点,那它绝对是nullptr指针(替换者至多有一个红色儿子,且该儿子没有后代)
643 
644     delete del;                                    // 删除节点并返回
645     del = nullptr;
646 }
647 
648 template <typename T>
649 bool RBTree<T>::remove(T key)
650 {
651     bool ret = false;
652     RBTNode<T>* node = search(mRoot, key);
653 
654     if ( node != nullptr )
655     {
656         remove(mRoot, node);
657         ret = true;
658     }
659 
660     return ret;
661 }
662 
663 template <typename T>
664 void RBTree<T>::printTree(RBTNode<T> const* const tree, bool firstNode) const
665 {
666     if ( tree==nullptr )
667         return;
668 
669     bool static outTag[64] = {false};    // size = max layer limit;
670     uint8_t static layer = 0;
671     uint8_t i;
672     ++layer;
673 
674     if ( layer >= 2 )
675     {
676         for (i=2; i<layer; ++i )
677             if ( outTag[i] )
678                 cout << "|       ";
679             else
680                 cout << "        ";
681         cout << "+-------" << flush;
682     }
683     cout << tree->mKey << ' ' << (tree->mColor==BLACK ? 'B' : 'R') << endl;
684 
685     for ( i=2-1; i>0; --i)        // 从右往左输出结点,即先打印最右边结点,其次次右边的结点;此循环不输出最左边的结点
686     {
687         if ( (tree->mLeft+i) != nullptr )    // 注意树的子结点指针必须是从左往右依次排列,中间不能有其它变量(left_1,left_2,left_3...left_n)
688         {                                    // 如果你的子结点数量不定,一定要把后面的首个指针设为nullptr
689             outTag[layer] = !firstNode;
690             printTree(tree->mRight, false);
691         }
692     }
693     if ( tree->mLeft != nullptr )            // 输出最左边的结点
694     {
695         printTree(tree->mLeft, true);
696         outTag[layer] = firstNode;
697     }
698 
699     --layer;
700 }
701 
702 template <typename T>
703 void RBTree<T>::printTree() const
704 {
705     printTree(mRoot, true);    // 右边参数此时无意义
706 }
707 
708 template <typename T>
709 void RBTree<T>::destroy(RBTNode<T>* &tree)
710 {
711     if ( tree == nullptr )
712         return;
713 
714     if ( tree->mLeft != nullptr )
715         destroy(tree->mLeft);
716     if ( tree->mRight != nullptr )
717         destroy(tree->mRight);
718 
719     delete tree;
720 }
721 
722 template <typename T>
723 void RBTree<T>::destroy()
724 {
725     destroy(mRoot);
726 
727     mRoot = nullptr;
728     mCount = 0ull;
729     mHeight = 0;
730 }
731 
732 template <typename T>
733 uint64_t RBTree<T>::getCount() const
734 {
735     return mCount;
736 }
737 
738 template <typename T>
739 uint16_t RBTree<T>::updateHeight(RBTNode<T> *node)
740 {
741     if ( node == nullptr )
742         return 0;
743 
744     return max(updateHeight(node->mLeft), updateHeight(node->mRight))+1;
745 }
746 
747 template <typename T>
748 uint16_t RBTree<T>::getHeight(bool update)
749 {
750     if ( update == true )
751         mHeight = updateHeight(mRoot);
752 
753     return mHeight;
754 }
755 
756 template <typename T>
757 uint16_t RBTree<T>::max(uint16_t left, uint16_t right) const
758 {
759     return (left > right) ? left : right;
760 }
761 
762 template <typename T>
763 bool RBTree<T>::rootIsNullptr() const
764 {
765     return mRoot==nullptr;
766 }
767 
768 template <typename T>
769 T RBTree<T>::getRootKey() const
770 {
771     return (rootIsNullptr()) ? ~0ull : mRoot->mKey;
772 }
773 
774 }
775 
776 #endif // RBTREE_H

main.cpp

 

  1 #include "RBTree.h"
  2 
  3 #include "Times.h"
  4 
  5 using namespace std;
  6 using namespace Viclib;
  7 
  8 typedef uint64_t templateType;
  9 typedef uint64_t sizeType;
 10 
 11 static bool checkTree(RBTree<templateType>* tree);
 12 
 13 int main(int argc, char* argv[])
 14 {
 15     // msys2终端1920*2宽424个英文字符
 16     uint16_t layer = 16;
 17 
 18     if ( argc == 2 && atoi(argv[1])>=0 )
 19         layer = static_cast<uint16_t>(atoi(argv[1]));
 20     else {
 21         cout << "请输入结点层数,注意内存大小" << endl;
 22         cin >> layer;
 23     }
 24 
 25     timingStart();
 26     cout << endl;
 27 
 28     uint64_t const count = (1ull<<layer)-1ull;
 29 
 30     cout << "您设定的最大层数上限:" << layer << endl;
 31     cout << "您设定的最大结点数上限:" << count << endl;
 32 
 33     templateType *t = nullptr, tmp = 0;
 34     RBTree<templateType>* tree = new RBTree<templateType>();
 35 
 36     cout << endl << "添加元素:\n\tkey\tcount\tlayer" << endl;
 37     srand(static_cast<uint32_t>(time(nullptr)));
 38     while ( tree->getCount() < count )
 39     {
 40         do
 41         {
 42             tmp = static_cast<templateType>(
 43                 static_cast<sizeType>(rand())
 44                 * static_cast<sizeType>(rand())
 45                 * static_cast<sizeType>(rand())
 46                 % (count*2));
 47         } while(tree->iterativeSearch(tmp));
 48         //tmp = setArr(count);
 49         tree->insert(tmp);
 50         //cout << "插入:\t" << tmp << "\t" << tree->getCount() << "\t" << tree->getHeight(true) << endl;
 51         
 52         if ( (tree->getCount()*100%count) == 0 || tree->getCount() == count )
 53             cout << "\r已添加:" << setw(2) << tree->getCount()*100.0/count << '%' << flush;
 54     }
 55     cout << endl;
 56 
 57     cout << "\n红黑树平衡校验结果:";
 58     if ( checkTree(tree) )
 59         cout << "成功\n" << endl;
 60     else
 61     {
 62         cout << "节点的路径与左边第一个节点路径黑色数量不同\n" << endl;
 63 
 64         cout << "输出目录树模式关系图:" << endl;
 65         tree->printTree();
 66         cout << endl;
 67 
 68         exit(1);
 69     }
 70 
 71     cout << "前序遍历: ";
 72     tree->preOrder();
 73     cout << "\n中序遍历: ";
 74     tree->inOrder();
 75     cout << "\n后序遍历: ";
 76     tree->postOrder();
 77     cout << "\n广度优先: ";
 78     tree->levelOrder();
 79     cout << endl;
 80 
 81     if ( (tree!=nullptr) && ((t = const_cast<templateType*>(tree->minimum())) != nullptr) )
 82         cout << "最小结点:" << *t << endl;
 83     if ( (tree!=nullptr) && ((t = const_cast<templateType*>(tree->maximum())) != nullptr) )
 84         cout << "最大结点:" << *t << endl;
 85     cout << "树的结点数:" << tree->getCount() << endl;
 86     cout << "树的高度(不含最底层叶节点):" << tree->getHeight(true) << endl;
 87 
 88 //    cout << "输出树形关系图:" << endl;
 89 //    tree->printGraph();
 90 //    cout << endl;
 91 
 92     cout << "输出目录树模式关系图:" << endl;
 93     tree->printTree();
 94     cout << endl;
 95 
 96     cout << "开始删除:\n\tkey\tcount\tlayer" << endl;
 97     srand(static_cast<uint32_t>(time(nullptr)));
 98     while ( !tree->rootIsNullptr() )        // 随机数删除
 99     {
100         do
101         {
102             tmp = static_cast<templateType>(
103                 static_cast<sizeType>(rand())
104                 * static_cast<sizeType>(rand())
105                 * static_cast<sizeType>(rand())
106                 % (count*2));
107         } while(!tree->iterativeSearch(tmp));
108         if ( tree->remove(tree->getRootKey()) )
109         {
110             //cout << "删除:\t" << tmp << "\t" << tree->getCount() << "\t" << tree->getHeight(true) << endl;
111 
112             if ( (tree->getCount()*100%count) == 0 || tree->getCount() == count )
113                 cout << "\r已删除:" << setw(2) << (count-tree->getCount())*100.0/count << '%' << flush;
114         }
115     }
116     cout << endl;
117 
118     tree->destroy();
119     tree = nullptr;
120 
121     cout << endl;
122     timingEnd();
123 
124     return 0;
125 }
126 
127 static bool checkTree(RBTree<templateType>* tree)
128 {
129     if ( tree == nullptr )
130         return true;
131 
132     queue<RBTNode<templateType>*> tmp;
133     tmp.push(tree->search(tree->getRootKey()));
134     queue<RBTNode<templateType>*> leaf;
135     RBTNode<templateType>* t;
136     uint8_t i = 0;
137     uint8_t j = 0;
138 
139     while( tmp.size() > 0 )
140     {
141         t = tmp.front();
142 
143         if ( t->mLeft != nullptr )
144             tmp.push(t->mLeft);
145         else
146             leaf.push(t);
147 
148         if ( t->mRight != nullptr )
149             tmp.push(t->mRight);
150         else
151             leaf.push(t);
152 
153         tmp.pop();
154     }
155 
156     t = leaf.front();
157     leaf.pop();
158     while ( t != nullptr )
159     {
160         if ( t->mColor == BLACK ) ++i;
161         t = t->mParent;
162     }
163 
164     while ( !leaf.empty() )
165     {
166         t = leaf.front();
167 
168         j = 0;
169         if ( t->mColor == BLACK ) ++j;
170         while ( t->mParent != nullptr )
171         {
172             t = t->mParent;
173             if ( t->mColor == BLACK ) ++j;
174         }
175 
176         if ( i != j )
177         {
178             cout << leaf.front()->mKey;
179             return false;
180         }
181 
182         leaf.pop();
183     }
184 
185     return true;
186 }

 

posted on 2019-05-20 00:12  Duacai  阅读(2598)  评论(0编辑  收藏  举报