标签: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
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 }
标签:using dex com tla 网站 private lse tps ref
原文地址:https://www.cnblogs.com/Dua677/p/10891660.html