第六十九课 二叉树的线索化实现

在工程中,很多时候二叉树一旦建立就不会轻易改动,这样的二叉树就用于遍历,我们讲了先序遍历、中序遍历、后续遍历三种方式,都是递归完成的,在工程中,如果对一棵二叉树反复的执行遍历,效率很低,递归的效率是比较低的。

改进的做法就是将遍历的结果保存下来,下一次遍历时直接用这个结果。

在工程中另一种需求就是,在中序遍历下,需要知道某一个节点的前驱是谁,后继是谁,需要这三个节点来判断是否执行后续的操作。这个时候又需要遍历了。每次都递归的进行遍历,效率太低了。

为了效率,我们使用线索化二叉树的方法,将二叉树转换为一个线性结构,这样效率就高了。

 

 

初始准备两个队列,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 }

结果如下:

小结:

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9695438.html