码迷,mamicode.com
首页 > 其他好文 > 详细

二叉树之红黑树(RBTree)

时间:2019-05-20 01:03:19      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:using   dex   com   tla   网站   private   lse   tps   ref   

  详解以后再补充。。。

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

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

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

技术图片技术图片

 

 

红黑树插入删除步骤

技术图片

 

输出

技术图片

代码

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

工程通过Qt Creator创建

RBTree.h

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

main.cpp

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

 

二叉树之红黑树(RBTree)

标签:using   dex   com   tla   网站   private   lse   tps   ref   

原文地址:https://www.cnblogs.com/Dua677/p/10891660.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!