二叉搜索樹(Binary Search Tree)node
引用:https://www.cnblogs.com/skywang12345/linux
詳解之後再補充。。。ios
代碼含註釋,下面是輸出效果(msys2)git
代碼github
開發環境:Qt Creator 4.8.2 Mingw64 7.3 windows 8.1windows
完整代碼:https://github.com/Duacai/Data-Structure-and-Algorithms/tree/master/Data-Structure/Tree/BSTreepost
BSTree.h
ui
1 #ifndef BSTREE_H 2 #define BSTREE_H 3 4 #include <iostream> 5 #include <queue> 6 7 using namespace std; 8 9 namespace Viclib 10 { 11 12 template < typename T > 13 class BSTNode 14 { 15 public: 16 T mKey; 17 BSTNode<T> *mLeft; 18 BSTNode<T> *mRight; 19 BSTNode<T> *mParent; 20 21 BSTNode() = delete; 22 BSTNode(const T& key, BSTNode<T> *left, BSTNode<T> *right, BSTNode<T> *parent); 23 BSTNode(const BSTNode<T>& tree) = delete; 24 BSTNode(BSTNode<T> && tree); 25 BSTNode<T>& operator = (const BSTNode<T>& tree) = delete; 26 BSTNode<T>& operator = (BSTNode<T> && tree); 27 virtual ~BSTNode(); 28 }; 29 30 template < typename T > 31 BSTNode<T>::BSTNode(const T& key, BSTNode<T> *left, BSTNode<T> *right, BSTNode<T> *parent) : 32 mKey(key), mLeft(left), mRight(right), mParent(parent) 33 { 34 } 35 36 template < typename T > 37 BSTNode<T>::BSTNode(BSTNode<T> && tree) 38 { 39 mLeft = tree.mLeft; 40 mRight = tree.mRight; 41 mParent = tree.mParent; 42 43 tree->mLeft = nullptr; 44 tree->mRight = nullptr; 45 tree->mParent = nullptr; 46 } 47 48 template < typename T > 49 BSTNode<T>& BSTNode<T>::operator = (BSTNode<T> && tree) 50 { 51 if ( this == &tree ) 52 return *this; 53 54 delete mLeft; 55 delete mRight; 56 delete mParent; 57 58 mLeft = tree->mLeft; 59 mRight = tree->mRight; 60 mParent = tree->mParent; 61 62 return *this; 63 } 64 65 template < typename T > 66 BSTNode<T>::~BSTNode() 67 { 68 } 69 70 template < typename T > 71 class BSTree 72 { 73 protected: 74 BSTNode<T>* mRoot; 75 size_t mCount; 76 77 virtual void preOrder(BSTNode<T> *tree) const; // 深度優先的前、中、後序遍歷 78 virtual void inOrder(BSTNode<T> *tree) const; 79 virtual void postOrder(BSTNode<T> *tree) const; 80 81 virtual void levelOrder(BSTNode<T> *tree) const; // 廣度優先 82 83 virtual BSTNode<T>* search(BSTNode<T> *tree, const T& key) const; // 遞歸版搜索 84 virtual BSTNode<T>* iterativeSearch(BSTNode<T> *tree, const T& key) const; // 非遞歸版搜索 85 86 virtual BSTNode<T>* minimum(BSTNode<T> *tree) const; // 獲取最小最大值 87 virtual BSTNode<T>* maximum(BSTNode<T> *tree) const; 88 89 virtual BSTNode<T>* successor(BSTNode<T> *node) const; // 查找後繼,即大於又最接近node的節點 90 virtual BSTNode<T>* predecessor(BSTNode<T> *node) const; // 查找前繼 91 92 virtual void insert(BSTNode<T> *node); 93 virtual BSTNode<T>* remove(BSTNode<T> *node); // 返回值用於刪除,返回值實際是替換結點 94 virtual void destroy(BSTNode<T> *tree); 95 96 void printTree(BSTNode<T> *tree, bool firstNode) const; // 打印樹,相似linux的tree命令 97 98 virtual int height(BSTNode<T> *tree) const; // 樹的高度 99 virtual int degree(BSTNode<T> *tree) const; // 結點的度數 100 101 public: 102 BSTree(); 103 BSTree(const BSTree<T>&) = default; 104 BSTree(BSTree<T> &&) = default; 105 BSTree<T>& operator = (const BSTree<T>&) = default; 106 BSTree<T>& operator = (BSTree<T> &&) = default; 107 virtual ~BSTree(); 108 109 virtual void preOrder() const; 110 virtual void inOrder() const; 111 virtual void postOrder() const; 112 113 virtual void levelOrder() const; 114 115 virtual BSTNode<T>* search(const T& key) const; 116 virtual BSTNode<T>* iterativeSearch(const T& key) const; 117 118 virtual const T& minimum() const; 119 virtual const T& maximum() const; 120 121 virtual void insert(const T& key); 122 virtual void remove(const T& key); 123 virtual void destroy(); 124 125 virtual int height() const; 126 virtual int degree() const; 127 128 virtual size_t getCount() const; 129 130 virtual const T& getRootKey() const; 131 virtual void printTree() const; 132 }; 133 134 template < typename T > 135 BSTree<T>::BSTree() : mRoot(nullptr), mCount(0) 136 { 137 } 138 139 template < typename T > 140 void BSTree<T>::preOrder(BSTNode<T> *tree) const 141 { 142 if ( tree != nullptr ) 143 { 144 cout << tree->mKey << " " << flush; 145 preOrder(tree->mLeft); 146 preOrder(tree->mRight); 147 } 148 } 149 150 template < typename T > 151 void BSTree<T>::preOrder() const 152 { 153 preOrder(dynamic_cast<BSTNode<T>*>(this->mRoot)); 154 } 155 156 template < typename T > 157 void BSTree<T>::inOrder(BSTNode<T> *tree) const 158 { 159 if ( tree != nullptr ) 160 { 161 inOrder(tree->mLeft); 162 cout << tree->mKey << " " << flush; 163 inOrder(tree->mRight); 164 } 165 } 166 167 template < typename T > 168 void BSTree<T>::inOrder() const 169 { 170 inOrder(dynamic_cast<BSTNode<T>*>(this->mRoot)); 171 } 172 173 template < typename T > 174 void BSTree<T>::postOrder(BSTNode<T> *tree) const 175 { 176 if ( tree != nullptr ) 177 { 178 postOrder(tree->mLeft); 179 postOrder(tree->mRight); 180 cout << tree->mKey << " " << flush; 181 } 182 } 183 184 template < typename T > 185 void BSTree<T>::postOrder() const 186 { 187 postOrder(dynamic_cast<BSTNode<T>*>(this->mRoot)); 188 } 189 190 template < typename T > 191 void BSTree<T>::levelOrder(BSTNode<T> *tree) const 192 { 193 if ( tree != nullptr ) 194 { 195 queue<BSTNode<T>*> tmp; 196 tmp.push(tree); 197 198 while( tmp.size() > 0 ) 199 { 200 BSTNode<T>* t = tmp.front(); 201 tmp.pop(); 202 203 if ( t->mLeft != nullptr ) 204 tmp.push(t->mLeft); 205 206 if ( t->mRight != nullptr ) 207 tmp.push(t->mRight); 208 209 cout << t->mKey << " " << flush; 210 } 211 } 212 } 213 214 template < typename T > 215 void BSTree<T>::levelOrder() const 216 { 217 levelOrder(dynamic_cast<BSTNode<T>*>(this->mRoot)); 218 } 219 220 template < typename T > 221 BSTNode<T>* BSTree<T>::search(BSTNode<T> *node, const T& key) const 222 { 223 if ( node == nullptr || node->mKey == key ) 224 { 225 return node; 226 } 227 else if ( key < node->mKey ) 228 return search(dynamic_cast<BSTNode<T>*>(node)->mLeft, key); 229 else 230 return search(dynamic_cast<BSTNode<T>*>(node)->mRight, key); 231 } 232 233 template < typename T > 234 BSTNode<T>* BSTree<T>::search(const T& key) const 235 { 236 return search(dynamic_cast<BSTNode<T>*>(this->mRoot), key); 237 } 238 239 template < typename T > 240 BSTNode<T>* BSTree<T>::iterativeSearch(BSTNode<T>* node, const T& key) const 241 { 242 while ( (node != nullptr) && (node->mKey != key) ) 243 { 244 if ( key < node->mKey ) 245 node = node->mLeft; 246 else 247 node = node->mRight; 248 } 249 250 return node; 251 } 252 253 template < typename T > 254 BSTNode<T>* BSTree<T>::iterativeSearch(const T& value) const 255 { 256 return iterativeSearch(dynamic_cast<BSTNode<T>*>(this->mRoot), value); 257 } 258 259 template < typename T > 260 BSTNode<T>* BSTree<T>::minimum(BSTNode<T>* tree) const 261 { 262 if ( tree == nullptr ) 263 return nullptr; 264 265 while ( tree->mLeft != nullptr ) 266 tree = tree->mLeft; 267 268 return tree; 269 } 270 271 template < typename T > 272 const T& BSTree<T>::minimum() const 273 { 274 BSTNode<T> *p = minimum(dynamic_cast<BSTNode<T>*>(this->mRoot)); 275 // if ( p == nullptr ) 276 // THROW_EXCEPTION(EmptyTreeException, "The tree is empty ..."); 277 278 return p->mKey; 279 } 280 281 template < typename T > 282 BSTNode<T>* BSTree<T>::maximum(BSTNode<T>* tree) const 283 { 284 if ( tree == nullptr ) 285 return nullptr; 286 287 while ( tree->mRight != nullptr ) 288 tree = tree->mRight; 289 290 return tree; 291 } 292 293 template < typename T > 294 const T& BSTree<T>::maximum() const 295 { 296 BSTNode<T> *p = maximum(dynamic_cast<BSTNode<T>*>(this->mRoot)); 297 // if ( p == nullptr ) 298 // THROW_EXCEPTION(EmptyTreeException, "The tree is empty ..."); 299 300 return p->mKey; 301 } 302 303 template < typename T > 304 BSTNode<T>* BSTree<T>::successor(BSTNode<T> *node) const // 查找後繼 305 { 306 if ( node->mRight != nullptr ) // 若是node有右孩子,則在它的右孩子裏面最小的是後繼 307 { 308 return minimum(node->mRight); 309 } 310 311 BSTNode<T>* ret = node->mParent; // 若是node沒有右孩子,且它自身是左孩子,則它的父親是後繼 312 while ( (ret != nullptr) && (node == ret->mRight) ) // 若是node沒有右孩子,且它自身是右孩子,它的最近祖先是左孩子的,則這個祖先的父親就是後繼 313 { 314 node = ret; 315 ret = ret->mParent; 316 } 317 318 return ret; 319 } 320 321 template < typename T > 322 BSTNode<T>* BSTree<T>::predecessor(BSTNode<T>* node) const // 查找前繼 323 { 324 if ( node->mLeft != nullptr ) // 若是node有左孩子,則在它的左孩子裏面最大的是前繼 325 return maximum(node->mLeft); 326 327 BSTNode<T>* ret = node->mParent; // 若是node沒有左孩子,且它自身是右孩子,則它的父親是後繼 328 while ( (ret != nullptr) && (node == ret->mLeft) ) // 若是node沒有左孩子,且它自身是左孩子,它的最近祖先是右孩子的,則這個祖先的父親就是後繼 329 { 330 node = ret; 331 ret = ret->mLeft; 332 } 333 334 return ret; 335 } 336 337 template < typename T > 338 void BSTree<T>::insert(BSTNode<T>* node) 339 { 340 BSTNode<T>* in = nullptr; // 插入點 341 BSTNode<T>* parent = dynamic_cast<BSTNode<T>*>(this->mRoot); // 插入點的父節點 342 343 while ( parent != nullptr ) // 查找node的插入點 344 { 345 in = parent; 346 if ( node->mKey < in->mKey ) // 若是node結點小於插入點,則插入到左孩子分支 347 parent = parent->mLeft; 348 else if ( node->mKey > in->mKey ) // 若是node結點大於插入點,則插入到右孩子分支 349 parent = parent->mRight; 350 else // 若是數據等同則跳出 351 break; 352 } 353 354 node->mParent = in; // 設置node結點的父親爲插入點 355 if ( in == nullptr ) // 若是插入點爲空,設node結點爲根節點 356 this->mRoot = node; 357 else if ( node->mKey < in->mKey ) // 若是node結點小於插入點,插入左邊 358 in->mLeft = node; 359 else if ( node->mKey > in->mKey ) // 若是node結點大於插入點,插入右邊 360 in->mRight = node; 361 else // 若是數據等同則直接替換並釋放插入的結點 362 { 363 in->mKey = node->mKey; 364 delete node; 365 return; 366 } 367 368 ++this->mCount; // 結點統計,注意重複結點插入時不能增長 369 } 370 371 template < typename T > 372 void BSTree<T>::insert(const T& key) 373 { 374 insert(new BSTNode<T>(key, nullptr, nullptr, nullptr)); 375 } 376 377 template < typename T > 378 BSTNode<T>* BSTree<T>::remove(BSTNode<T> *node) 379 { 380 BSTNode<T>* replace = nullptr; // 代替結點 381 BSTNode<T>* del = nullptr; // 刪除點 382 383 if ( (node->mLeft == nullptr) || (node->mRight == nullptr) ) // 若是孩子不全,node就是刪除點,能夠直接用僅有的孩子代替 384 del = node; 385 else // 不然有兩個孩子,後繼就是刪除點(右子樹中最小的成員) 386 { 387 del = successor(node); // 查找後繼 388 node->mKey = del->mKey; // 直接用後繼key替換node的key 389 } 390 391 if ( del->mLeft != nullptr ) // 若是有左孩子,則更新左孩子爲代替結點(若是if成立就只有左孩子) 392 replace = del->mLeft; 393 else // 不然設右孩子爲代替結點 394 replace = del->mRight; 395 396 if ( replace != nullptr ) // 若是代替結點不是空樹,更新代替結點的父親 397 replace->mParent = del->mParent; 398 399 if ( del->mParent == nullptr ) // 若是結點是根節點且孩子不全,那就直接替換 400 this->mRoot = replace; 401 else if ( del == del->mParent->mLeft ) // 若是刪除點爲左孩子,則更新父節點的左孩子 402 del->mParent->mLeft = replace; 403 else // 不然更新父節點的右孩子 404 del->mParent->mRight = replace; 405 406 --this->mCount; 407 408 return del; 409 } 410 411 template < typename T > 412 void BSTree<T>::remove(const T& key) 413 { 414 BSTNode<T> *del = nullptr, *node; 415 del = search(dynamic_cast<BSTNode<T>*>(this->mRoot), key); 416 417 if ( del != nullptr ) // 找到的刪除點不爲空 418 if ( (node = remove(del)) != nullptr ) // 刪除node並返回代替結點 419 delete node; // 刪除代替結點 420 } 421 422 template < typename T > 423 void BSTree<T>::destroy(BSTNode<T> *tree) 424 { 425 if ( tree == nullptr ) 426 return; 427 428 if ( tree->mLeft != nullptr ) 429 destroy(tree->mLeft); 430 431 if ( tree->mRight != nullptr ) 432 destroy(tree->mRight); 433 434 delete tree; 435 tree = nullptr; 436 } 437 438 template < typename T > 439 void BSTree<T>::destroy() 440 { 441 destroy(dynamic_cast<BSTNode<T>*>(this->mRoot)); 442 this->mRoot = nullptr; 443 this->mCount = 0; 444 } 445 446 template < typename T > 447 int BSTree<T>::height(BSTNode<T>* node) const 448 { 449 int ret = 0; 450 451 if( node != nullptr ) 452 { 453 int lh = height(node->mLeft); 454 int rh = height(node->mRight); 455 456 ret = ((lh > rh) ? lh : rh) + 1; 457 } 458 459 return ret; 460 } 461 462 template < typename T > 463 int BSTree<T>::height() const 464 { 465 int ret = 0; 466 467 if( this->mRoot != nullptr ) 468 { 469 ret = height(dynamic_cast<BSTNode<T>*>(this->mRoot)); 470 } 471 472 return ret; 473 } 474 475 template < typename T > 476 int BSTree<T>::degree(BSTNode<T>* node) const 477 { 478 int ret = 0; 479 480 if( node != nullptr ) 481 { 482 BSTNode<T>* child[] = { node->mLeft, node->mRight }; 483 484 ret = (!!node->mLeft + !!node->mRight); // 統計有效結點數,!!用於轉換成bool類型,若是是有效結點則爲1,不然爲0 485 486 for(int i=0; (i<2) && (ret<2); i++) // 若是兒子不足2個須要檢查 487 { 488 int d = degree(child[i]); 489 490 if( ret < d ) 491 { 492 ret = d; 493 } 494 } 495 } 496 497 return ret; 498 } 499 500 template < typename T > 501 int BSTree<T>::degree() const 502 { 503 return degree(dynamic_cast<BSTNode<T>*>(this->mRoot)); 504 } 505 506 template < typename T > 507 size_t BSTree<T>::getCount() const 508 { 509 return this->mCount; 510 } 511 512 template <typename T> 513 void BSTree<T>::printTree(BSTNode<T> *tree, bool firstNode) const 514 { 515 if ( tree == nullptr ) 516 return; 517 518 size_t height = this->height(); // 樹的高度 519 static bool *outTag = new bool[height](); // 左邊是否還有結點的標記,初始化爲false 520 uint8_t static layer = 0; // 當前層數,根結點爲第一層 521 uint8_t i; 522 ++layer; 523 524 if ( layer > 1 ) // 若是不是根節點須要輸出特殊符號 525 { 526 for (i=1; i<layer-1; ++i ) // 根節點和最後一個結點不須要,因此從1至(layer-1) 527 if ( outTag[i] ) // 若是左邊還有結點 528 cout << "| "; 529 else 530 cout << " "; 531 532 if ( firstNode == true ) // 判斷左右結點,非二叉樹須要另外處理 533 cout << "L-------" << flush; 534 else 535 cout << "R-------" << flush; 536 } 537 cout << tree->mKey << endl; 538 539 if ( (tree->mRight) != nullptr ) // 先輸出右節點 540 { 541 if ( tree->mLeft != nullptr ) // 若是左邊還有結點須要作標記 542 outTag[layer] = true; 543 printTree(tree->mRight, false); // false表示當前是右節點 544 } 545 546 if ( tree->mLeft != nullptr ) 547 { 548 outTag[layer] = false; // 左結點左邊再也不有結點,恢復默認標記 549 printTree(tree->mLeft, true); 550 } 551 552 --layer; // 結點回溯時高度須要減1 553 } 554 555 template <typename T> 556 void BSTree<T>::printTree() const 557 { 558 printTree(dynamic_cast<BSTNode<T>*>(this->mRoot), false); // 做爲根節點時,右參數無心義 559 } 560 561 template < typename T > 562 const T& BSTree<T>::getRootKey() const 563 { 564 return this->mRoot->mKey; 565 } 566 567 template < typename T > 568 BSTree<T>::~BSTree() 569 { 570 destroy(); 571 } 572 573 } 574 575 #endif // BSTREE_H
main.cppthis
1 #include <iostream> 2 #include <iomanip> 3 #include <cmath> 4 5 #include "BSTree.h" 6 7 #include "Times.h" 8 9 using namespace std; 10 using namespace Viclib; 11 12 int main(int argc, char* argv[]) 13 { 14 uint16_t layer = 8; // 結點最小層數 15 16 if ( argc == 2 && atoi(argv[1])>0 ) 17 layer = static_cast<uint8_t>(atoi(argv[1])); 18 else { 19 cout << "請輸入結點最小層數,注意內存大小" << log(RAND_MAX*RAND_MAX+1+RAND_MAX*2)/log(2) << endl; 20 cin >> layer; 21 } 22 23 timingStart(); // 啓動計時 24 25 cout << endl; 26 27 uint64_t const count = (1ull<<layer)-1; // 結點數 28 uint16_t speed; // 記錄插入和刪除的進度百分比(0~100) 29 30 BSTree<uint64_t> *tree = new BSTree<uint64_t>(); 31 32 speed = 0; 33 srand(static_cast<unsigned int>(time(nullptr))); 34 while ( tree->getCount() < count ) 35 { 36 tree->insert(static_cast<size_t>(rand()*rand()+1+RAND_MAX*2)); // 使用隨機值插入;若是是順序值,會退化成鏈表模式,且插入變慢 37 38 if ( (tree->getCount()*100/count > speed) || (tree->getCount() == count) ) // 進度值出現變化或完成操做時才能輸出 39 { 40 speed = static_cast<uint16_t>(tree->getCount()*100/count); 41 cout << "\r已添加:" << setw(3) << speed << '%' << flush; 42 } 43 } 44 cout << endl; 45 46 cout << "\n前序遍歷: "; 47 tree->preOrder(); 48 cout << endl; 49 50 cout << "\n中序遍歷: "; 51 tree->inOrder(); 52 cout << endl; 53 54 cout << "\n後續遍歷: "; 55 tree->postOrder(); 56 cout << endl; 57 58 cout << "\n廣度遍歷:"; 59 tree->levelOrder(); 60 cout << endl; 61 62 cout << "\n最小值: " << tree->minimum(); 63 cout << "\n最大值: " << tree->maximum(); 64 cout << "\n樹高度 = " << tree->height(); 65 cout << "\n結點數= " << tree->getCount(); 66 cout << endl; 67 68 cout << "\n輸出樹形信息:" << endl; 69 tree->printTree(); 70 cout << endl; 71 72 speed = 0; 73 srand(static_cast<unsigned int>(time(nullptr))); 74 while ( tree->getCount() ) 75 { 76 uint64_t node; 77 // if ( tree->getCount()*100/count < 20 ) // 剩餘量太少時,隨機值命中有效結點的機率過低,從而致使刪除緩慢 78 node = tree->getRootKey(); 79 // else 80 // node = static_cast<size_t>(rand()*rand()+1+RAND_MAX*2); 81 82 tree->remove(node); 83 84 if ( ((count-tree->getCount())*100/count > speed) || (tree->getCount() == count) ) 85 { 86 speed = static_cast<uint16_t>((count-tree->getCount())*100/count); 87 cout << "\r已刪除:" << setw(3) << speed << '%' << flush; 88 } 89 } 90 cout << endl; 91 92 tree->destroy(); 93 delete tree; 94 tree = nullptr; 95 96 cout << endl; 97 timingEnd(); 98 99 return 0; 100 }