二叉树之红黑树(RBTree)
Posted Duacai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树之红黑树(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 二叉查找树之红黑树