在工程中,很多时候二叉树一旦建立就不会轻易改动,这样的二叉树就用于遍历,我们讲了先序遍历、中序遍历、后续遍历三种方式,都是递归完成的,在工程中,如果对一棵二叉树反复的执行遍历,效率很低,递归的效率是比较低的。
改进的做法就是将遍历的结果保存下来,下一次遍历时直接用这个结果。
在工程中另一种需求就是,在中序遍历下,需要知道某一个节点的前驱是谁,后继是谁,需要这三个节点来判断是否执行后续的操作。这个时候又需要遍历了。每次都递归的进行遍历,效率太低了。
为了效率,我们使用线索化二叉树的方法,将二叉树转换为一个线性结构,这样效率就高了。
初始准备两个队列,tmp队列用于层次遍历,出队的时候将元素放到queue中,queue队列负责线索化。
新添加层次遍历函数的流程如下:
添加层次遍历函数:
1 void levelOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue) 2 { 3 if( node != NULL ) 4 { 5 LinkQueue<BTreeNode<T>*> tmp; 6 7 tmp.add(node); 8 9 while( tmp.length() > 0 ) 10 { 11 BTreeNode<T>* n = tmp.front(); 12 13 if( n->left != NULL ) 14 { 15 tmp.add(n->left); 16 } 17 18 if( n->right != NULL ) 19 { 20 tmp.add(n->right); 21 } 22 23 tmp.remove(); 24 queue.add(n); 25 } 26 } 27 }
添加连接操作和线索化操作:
1 #ifndef BTREE_H 2 #define BTREE_H 3 4 #include "Tree.h" 5 #include "BTreeNode.h" 6 #include "Exception.h" 7 #include "LinkQueue.h" 8 #include "DynamicArray.h" 9 10 11 namespace DTLib 12 { 13 14 enum BTTraversal 15 { 16 PreOrder, 17 InOrder, 18 PostOrder, 19 LevelOrder 20 }; 21 22 template < typename T > 23 class BTree : public Tree<T> 24 { 25 protected: 26 LinkQueue<BTreeNode<T>*> m_queue; 27 //定义递归功能函数 28 virtual BTreeNode<T>* find(BTreeNode<T>* node, const T& value) const 29 { 30 BTreeNode<T>* ret = NULL; 31 32 if( node != NULL ) 33 { 34 if( node->value == value ) 35 { 36 ret = node; 37 } 38 else 39 { 40 if( ret == NULL ) 41 { 42 ret = find(node->left, value); 43 } 44 45 if( ret == NULL ) 46 { 47 ret = find(node->right, value); 48 } 49 } 50 } 51 52 return ret; 53 } 54 55 virtual BTreeNode<T>* find(BTreeNode<T>* node, BTreeNode<T>* obj) const 56 { 57 BTreeNode<T>* ret = NULL; 58 59 if( node == obj ) 60 { 61 ret = node; 62 } 63 else 64 { 65 if( node != NULL ) 66 { 67 if( ret == NULL ) 68 { 69 ret = find(node->left, obj); 70 } 71 72 if( ret == NULL ) 73 { 74 ret = find(node->right, obj); 75 } 76 } 77 } 78 79 return ret; 80 } 81 82 virtual bool insert(BTreeNode<T>* n, BTreeNode<T>* np, BTNodePos pos) 83 { 84 bool ret = true; 85 86 if( pos == ANY ) 87 { 88 if( np->left == NULL ) 89 { 90 np->left = n; 91 } 92 else if( np->right == NULL ) 93 { 94 np->right = n; 95 } 96 else 97 { 98 ret = false; 99 } 100 } 101 else if( pos == LEFT ) 102 { 103 if( np->left == NULL ) 104 { 105 np->left = n; 106 } 107 else 108 { 109 ret = false; 110 } 111 } 112 else if( pos == RIGHT ) 113 { 114 if( np->right == NULL ) 115 { 116 np->right = n; 117 } 118 else 119 { 120 ret = false; 121 } 122 } 123 else 124 { 125 ret = false; 126 } 127 128 return ret; 129 } 130 131 virtual void remove(BTreeNode<T>* node, BTree<T>*& ret) 132 { 133 ret = new BTree<T>(); 134 135 if( ret == NULL ) 136 { 137 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create btree..."); 138 } 139 else 140 { 141 if( root() == node ) 142 { 143 this->m_root = NULL; 144 } 145 else 146 { 147 BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent); 148 149 if( parent->left == node ) 150 { 151 parent->left = NULL; 152 } 153 else if( parent->right == node ) 154 { 155 parent->right = NULL; 156 } 157 158 node->parent = NULL; 159 } 160 161 ret->m_root = node; //作为子树返回 162 } 163 } 164 165 virtual void free(BTreeNode<T>* node) 166 { 167 if( node != NULL ) 168 { 169 free(node->left); 170 free(node->right); 171 172 if( node->flag() ) 173 { 174 delete node; 175 } 176 } 177 } 178 #if 0 179 int count(BTreeNode<T>* node) const 180 { 181 int ret = 0; 182 183 if( node != NULL ) 184 { 185 ret = count(node->left) + count(node->right) + 1; 186 } 187 188 return ret; 189 } 190 #endif 191 192 int count(BTreeNode<T>* node) const 193 { 194 return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0; 195 } 196 197 int height(BTreeNode<T>* node) const 198 { 199 int ret = 0; 200 201 if( node != NULL ) 202 { 203 int lh = height(node->left); 204 int rh = height(node->right); 205 206 ret = ((lh > rh) ? lh : rh) + 1;; 207 } 208 209 return ret; 210 } 211 212 #if 0 213 int degree(BTreeNode<T>* node) const 214 { 215 int ret = 0; 216 217 if( node != NULL ) 218 { 219 int dl = degree(node->left); 220 int dr = degree(node->right); 221 222 ret = (!!node->left + !!node->right); 223 224 if( ret < dl ) 225 { 226 ret = dl; 227 } 228 229 if( ret < dr ) 230 { 231 ret = dr; 232 } 233 } 234 235 return ret; 236 } 237 #endif 238 //二叉树的最大度数为2,上面的实现效率太低 239 int degree(BTreeNode<T>* node) const 240 { 241 int ret = 0; 242 243 if( node != NULL ) 244 { 245 BTreeNode<T>* child[] = {node->left, node->right}; 246 247 ret = (!!node->left + !!node->right); 248 249 for( int i = 0; (i < 2) && (ret < 2); i++) 250 { 251 int d = degree(child[i]); 252 253 if( ret < d ) 254 { 255 ret = d; 256 } 257 } 258 } 259 260 return ret; 261 } 262 263 void preOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue) 264 { 265 if( node != NULL ) 266 { 267 queue.add(node); 268 preOrderTraversal(node->left, queue); 269 preOrderTraversal(node->right, queue); 270 } 271 } 272 273 void inOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue) 274 { 275 if( node != NULL ) 276 { 277 inOrderTraversal(node->left, queue); 278 queue.add(node); 279 inOrderTraversal(node->right, queue); 280 } 281 } 282 283 void postOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue) 284 { 285 if( node != NULL ) 286 { 287 postOrderTraversal(node->left, queue); 288 postOrderTraversal(node->right, queue); 289 queue.add(node); 290 } 291 } 292 293 void levelOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue) 294 { 295 if( node != NULL ) 296 { 297 LinkQueue<BTreeNode<T>*> tmp; 298 299 tmp.add(node); 300 301 while( tmp.length() > 0 ) 302 { 303 BTreeNode<T>* n = tmp.front(); 304 305 if( n->left != NULL ) 306 { 307 tmp.add(n->left); 308 } 309 310 if( n->right != NULL ) 311 { 312 tmp.add(n->right); 313 } 314 315 tmp.remove(); 316 queue.add(n); 317 } 318 } 319 } 320 321 BTreeNode<T>* clone(BTreeNode<T>* node) const 322 { 323 BTreeNode<T>* ret = NULL; 324 325 if( node != NULL ) 326 { 327 ret = BTreeNode<T>::NewNode(); 328 329 if( ret != NULL ) 330 { 331 ret->value = node->value; 332 333 ret->left = clone(node->left); 334 ret->right = clone(node->right); 335 336 if( ret->left != NULL ) 337 { 338 ret->left->parent = ret; 339 } 340 341 if( ret->right != NULL ) 342 { 343 ret->right->parent = ret; 344 } 345 } 346 else 347 { 348 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node..."); 349 } 350 } 351 352 return ret; 353 } 354 355 bool equal(BTreeNode<T>* lh, BTreeNode<T>* rh) const 356 { 357 if( lh == rh ) 358 { 359 return true; 360 } 361 else if( (lh != NULL) && (rh != NULL) ) 362 { 363 return (lh->value == rh->value) && equal(lh->left, rh->left) && equal(lh->right, rh->right); 364 } 365 else 366 { 367 return false; 368 } 369 } 370 371 BTreeNode<T>* add(BTreeNode<T>* lh, BTreeNode<T>* rh) const 372 { 373 BTreeNode<T>* ret = NULL; 374 375 if( (lh == NULL) && (rh != NULL) ) 376 { 377 ret = clone(rh); 378 } 379 else if( (lh != NULL) && (rh == NULL) ) 380 { 381 ret = clone(lh); 382 } 383 else if( (lh != NULL) && (rh != NULL) ) 384 { 385 ret = BTreeNode<T>::NewNode(); 386 387 if( ret != NULL ) 388 { 389 ret->value = lh->value + rh->value; 390 391 ret->left = add(lh->left, rh->left); 392 ret->right = add(lh->right, rh->right); 393 394 if( ret->left != NULL ) 395 { 396 ret->left->parent = ret; 397 } 398 399 if( ret->right != NULL ) 400 { 401 ret->right->parent = ret; 402 } 403 } 404 else 405 { 406 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create tree..."); 407 } 408 } 409 410 return ret; 411 } 412 413 //重载一个traversal函数 414 void traversal(BTTraversal order, LinkQueue< BTreeNode<T>*>& queue) 415 { 416 switch( order ) 417 { 418 case PreOrder: 419 preOrderTraversal(root(), queue); 420 break; 421 case InOrder: 422 inOrderTraversal(root(), queue); 423 break; 424 case PostOrder: 425 postOrderTraversal(root(), queue); 426 break; 427 case LevelOrder: 428 levelOrderTraversal(root(), queue); 429 break; 430 default: 431 THROW_EXCEPTION(InvalidParameterException, "parameter is invalid..."); 432 break; 433 } 434 } 435 436 BTreeNode<T>* connect(LinkQueue<BTreeNode<T>*>& queue) 437 { 438 BTreeNode<T>* ret = NULL; 439 440 if( queue.length() > 0 ) 441 { 442 ret = queue.front(); 443 444 BTreeNode<T>* slider = queue.front(); 445 446 queue.remove(); 447 448 slider->left = NULL; 449 450 while( queue.length() > 0 ) 451 { 452 slider->right = queue.front(); 453 queue.front()->left = slider; 454 455 slider = queue.front(); 456 queue.remove(); 457 } 458 459 slider->right = NULL; 460 } 461 462 return ret; 463 } 464 public: 465 bool insert(TreeNode<T>* node) 466 { 467 return insert(node, ANY); 468 } 469 470 virtual bool insert(TreeNode<T>* node, BTNodePos pos) 471 { 472 bool ret = true; 473 474 if( node != NULL ) 475 { 476 if( this->m_root == NULL ) //空树 477 { 478 node->parent = NULL; 479 this->m_root = node; 480 } 481 else 482 { 483 BTreeNode<T>* np = find(node->parent); 484 485 if( np != NULL ) 486 { 487 ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos); 488 } 489 else 490 { 491 THROW_EXCEPTION(InvalidParameterException, "invalid parent tree node..."); 492 } 493 } 494 } 495 else 496 { 497 THROW_EXCEPTION(InvalidParameterException, "parameter node can not be null..."); 498 } 499 500 return ret; 501 } 502 503 bool insert(const T& value, TreeNode<T>* parent) 504 { 505 return insert(value, parent, ANY); 506 } 507 508 virtual bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos) 509 { 510 bool ret = true; 511 BTreeNode<T>* node = BTreeNode<T>::NewNode(); 512 513 if( node == NULL ) 514 { 515 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node..."); 516 } 517 else 518 { 519 node->value = value; 520 node->parent = parent; 521 522 ret = insert(node, pos); 523 524 if( !ret ) 525 { 526 delete node; 527 } 528 } 529 530 return ret; 531 } 532 533 SharedPointer< Tree<T> > remove(TreeNode<T>* node) //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,//这样有机会对里面的元素做进一步操作 534 { 535 BTree<T>* ret = NULL; 536 537 node = find(node); 538 539 if( node == NULL ) 540 { 541 THROW_EXCEPTION(InvalidParameterException, "parameter is invalid..."); 542 } 543 else 544 { 545 remove(dynamic_cast<BTreeNode<T>*>(node), ret); 546 547 m_queue.clear(); 548 } 549 550 return ret; 551 } 552 553 SharedPointer< Tree<T> > remove(const T& value) 554 { 555 BTree<T>* ret = NULL; 556 557 BTreeNode<T>* node = find(value); 558 559 if( node == NULL ) 560 { 561 THROW_EXCEPTION(InvalidParameterException, "can not find node via value..."); 562 } 563 else 564 { 565 remove(node, ret); 566 567 m_queue.clear(); 568 } 569 570 return ret; 571 } 572 573 BTreeNode<T>* find(const T& value) const 574 { 575 return find(root(), value); 576 } 577 578 BTreeNode<T>* find(TreeNode<T>* node) const 579 { 580 return find(root(), dynamic_cast<BTreeNode<T>*>(node)); 581 } 582 583 BTreeNode<T>* root() const 584 { 585 return dynamic_cast<BTreeNode<T>*>(this->m_root); 586 } 587 588 int degree() const 589 { 590 return degree(root()); 591 } 592 593 int count() const 594 { 595 return count(root()); 596 } 597 598 int height() const 599 { 600 return height(root()); 601 } 602 603 void clear() 604 { 605 free(root()); 606 607 m_queue.clear(); 608 609 this->m_root = NULL; 610 } 611 612 bool begin() 613 { 614 bool ret = ( root() != NULL ); 615 616 if( ret ) 617 { 618 m_queue.clear(); 619 m_queue.add(root()); 620 } 621 622 return ret; 623 } 624 625 bool end() 626 { 627 return (m_queue.length() == 0); 628 } 629 630 bool next() 631 { 632 bool ret = (m_queue.length() > 0); 633 634 if( ret ) 635 { 636 BTreeNode<T>* node = m_queue.front(); 637 638 m_queue.remove(); //将对头元素出队,相当于移动游标 639 640 if( node->left != NULL ) 641 { 642 m_queue.add(node->left); 643 } 644 645 if( node->right ) 646 { 647 m_queue.add(node->right); 648 } 649 } 650 651 return ret; 652 } 653 654 T current() 655 { 656 if( !end() ) //遍历的过程当中调用current函数才有意义 657 { 658 return m_queue.front()->value; 659 } 660 else 661 { 662 THROW_EXCEPTION(InvalidOperationException, "No value at current position..."); 663 } 664 } 665 666 SharedPointer< Array<T> > traversal(BTTraversal order) 667 { 668 DynamicArray<T>* ret = NULL; 669 LinkQueue<BTreeNode<T>*> queue; 670 671 traversal(order, queue); 672 673 ret = new DynamicArray<T>(queue.length()); 674 //遍历完将结果保存到动态数组中去 675 if( ret != NULL ) 676 { 677 for(int i = 0; i < ret->length(); i++, queue.remove()) 678 { 679 ret->set(i, queue.front()->value); 680 } 681 } 682 else 683 { 684 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create array..."); 685 } 686 687 return ret; 688 } 689 690 SharedPointer< BTree<T> > clone() const 691 { 692 BTree<T>* ret = new BTree<T>(); 693 694 if( ret != NULL ) 695 { 696 ret->m_root = clone(root()); 697 } 698 else 699 { 700 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create new btree..."); 701 } 702 703 return ret; 704 } 705 706 bool operator == (const BTree<T>& btree) 707 { 708 return equal(root(), btree.root()); 709 } 710 711 bool operator != (const BTree<T>& btree) 712 { 713 return !(*this == btree); 714 } 715 716 SharedPointer< BTree<T> > add(const BTree<T>& btree) const 717 { 718 BTree<T>* ret = new BTree<T>(); 719 720 if( ret != NULL ) 721 { 722 ret->m_root = add(root(), btree.root()); 723 } 724 else 725 { 726 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create new tree..."); 727 } 728 729 return ret; 730 } 731 732 BTreeNode<T>* thread(BTTraversal order) 733 { 734 BTreeNode<T>* ret = NULL; 735 LinkQueue<BTreeNode<T>*> queue; 736 737 traversal(order, queue); 738 739 ret = connect(queue); 740 741 this->m_root = NULL; 742 743 m_queue.clear(); 744 745 return ret; 746 } 747 748 ~BTree() 749 { 750 clear(); 751 } 752 }; 753 754 } 755 756 #endif // BTREE_H
测试程序如下:
1 #include <iostream> 2 #include "GTree.h" 3 #include "GTreeNode.h" 4 #include "BTree.h" 5 #include "BTreeNode.h" 6 7 8 using namespace std; 9 using namespace DTLib; 10 11 12 int main() 13 { 14 BTree<int> bt; 15 BTreeNode<int>* n = NULL; 16 17 bt.insert(1, NULL); 18 19 n = bt.find(1); 20 bt.insert(2, n); 21 bt.insert(3, n); 22 23 n = bt.find(2); 24 bt.insert(4, n); 25 bt.insert(5, n); 26 27 n = bt.find(4); 28 bt.insert(8, n); 29 bt.insert(9, n); 30 31 n = bt.find(5); 32 bt.insert(10, n); 33 34 n = bt.find(3); 35 bt.insert(6, n); 36 bt.insert(7, n); 37 38 39 cout << bt.count() << endl; 40 cout << bt.height() << endl; 41 cout << bt.degree() << endl; 42 43 44 SharedPointer< Array<int> > tr = bt.traversal(LevelOrder); 45 46 for(int i = 0; i < tr->length(); i++) 47 { 48 cout << (*tr)[i] << " "; 49 } 50 51 cout << endl; 52 53 BTreeNode<int>* head = bt.thread(LevelOrder); 54 55 while( head->right != NULL ) 56 { 57 head = head->right; 58 } 59 60 while( head != NULL ) 61 { 62 cout << head->value << " "; 63 head = head->left; 64 } 65 66 cout << endl; 67 68 return 0; 69 }
结果如下:
小结: