第六十七课 二叉树的典型遍历方式

 

 在BTree.h中添加遍历函数:

  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 };
 20 
 21 template < typename T >
 22 class BTree : public Tree<T>
 23 {
 24 protected:
 25     LinkQueue<BTreeNode<T>*> m_queue;
 26     //定义递归功能函数
 27     virtual BTreeNode<T>* find(BTreeNode<T>* node, const T& value) const
 28     {
 29         BTreeNode<T>* ret = NULL;
 30 
 31         if( node != NULL )
 32         {
 33             if( node->value == value )
 34             {
 35                 ret = node;
 36             }
 37             else
 38             {
 39                 if( ret == NULL )
 40                 {
 41                     ret = find(node->left, value);
 42                 }
 43 
 44                 if( ret == NULL )
 45                 {
 46                     ret = find(node->right, value);
 47                 }
 48             }
 49         }
 50 
 51         return ret;
 52     }
 53 
 54     virtual BTreeNode<T>* find(BTreeNode<T>* node, BTreeNode<T>* obj) const
 55     {
 56         BTreeNode<T>* ret = NULL;
 57 
 58         if( node == obj )
 59         {
 60             ret = node;
 61         }
 62         else
 63         {
 64             if( node != NULL )
 65             {
 66                 if( ret == NULL )
 67                 {
 68                     ret = find(node->left, obj);
 69                 }
 70 
 71                 if( ret == NULL )
 72                 {
 73                     ret = find(node->right, obj);
 74                 }
 75             }
 76         }
 77 
 78         return ret;
 79     }
 80 
 81     virtual bool insert(BTreeNode<T>* n, BTreeNode<T>* np, BTNodePos pos)
 82     {
 83         bool ret = true;
 84 
 85         if( pos == ANY )
 86         {
 87             if( np->left == NULL )
 88             {
 89                 np->left = n;
 90             }
 91             else if( np->right == NULL )
 92             {
 93                 np->right = n;
 94             }
 95             else
 96             {
 97                 ret = false;
 98             }
 99         }
100         else if( pos == LEFT )
101         {
102             if( np->left == NULL )
103             {
104                 np->left = n;
105             }
106             else
107             {
108                 ret = false;
109             }
110         }
111         else if( pos == RIGHT )
112         {
113             if( np->right == NULL )
114             {
115                 np->right = n;
116             }
117             else
118             {
119                 ret = false;
120             }
121         }
122         else
123         {
124             ret = false;
125         }
126 
127         return ret;
128     }
129 
130     virtual void remove(BTreeNode<T>* node, BTree<T>*& ret)
131     {
132         ret = new BTree<T>();
133 
134         if( ret == NULL )
135         {
136             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create btree...");
137         }
138         else
139         {
140             if( root() == node )
141             {
142                 this->m_root = NULL;
143             }
144             else
145             {
146                 BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent);
147 
148                 if( parent->left == node )
149                 {
150                     parent->left = NULL;
151                 }
152                 else if( parent->right == node )
153                 {
154                     parent->right = NULL;
155                 }
156 
157                 node->parent = NULL;
158             }
159 
160             ret->m_root = node;  //作为子树返回
161         }
162     }
163 
164     virtual void free(BTreeNode<T>* node)
165     {
166         if( node != NULL )
167         {
168             free(node->left);
169             free(node->right);
170 
171             if( node->flag() )
172             {
173                 delete node;
174             }
175         }
176     }
177     #if 0
178     int count(BTreeNode<T>* node) const
179     {
180         int ret = 0;
181 
182         if( node != NULL )
183         {
184             ret = count(node->left) + count(node->right) + 1;
185         }
186 
187         return ret;
188     }
189     #endif
190 
191     int count(BTreeNode<T>* node) const
192     {
193         return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0;
194     }
195 
196     int height(BTreeNode<T>* node) const
197     {
198         int ret = 0;
199 
200         if( node != NULL )
201         {
202             int lh = height(node->left);
203             int rh = height(node->right);
204 
205             ret = ((lh > rh) ? lh : rh) + 1;;
206         }
207 
208         return ret;
209     }
210 
211 #if 0
212     int degree(BTreeNode<T>* node) const
213     {
214         int ret = 0;
215 
216         if( node != NULL )
217         {
218             int dl = degree(node->left);
219             int dr = degree(node->right);
220 
221             ret = (!!node->left + !!node->right);
222 
223             if( ret < dl )
224             {
225                 ret = dl;
226             }
227 
228             if( ret < dr )
229             {
230                 ret = dr;
231             }
232         }
233 
234         return ret;
235     }
236 #endif
237 //二叉树的最大度数为2,上面的实现效率太低
238     int degree(BTreeNode<T>* node) const
239     {
240         int ret = 0;
241 
242         if( node != NULL )
243         {
244             BTreeNode<T>* child[] = {node->left, node->right};
245 
246             ret = (!!node->left + !!node->right);
247 
248             for( int i = 0; (i < 2) && (ret < 2); i++)
249             {
250                 int d = degree(child[i]);
251 
252                 if( ret < d )
253                 {
254                     ret = d;
255                 }
256             }
257         }
258 
259         return ret;
260     }
261 
262     void preOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
263     {
264         if( node != NULL )
265         {
266             queue.add(node);
267             preOrderTraversal(node->left, queue);
268             preOrderTraversal(node->right, queue);
269         }
270     }
271 
272     void inOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
273     {
274         if( node != NULL )
275         {
276             inOrderTraversal(node->left, queue);
277             queue.add(node);
278             inOrderTraversal(node->right, queue);
279         }
280     }
281 
282     void postOrderTraversal(BTreeNode<T>* node, LinkQueue<BTreeNode<T>*>& queue)
283     {
284         if( node != NULL )
285         {
286             postOrderTraversal(node->left, queue);
287             postOrderTraversal(node->right, queue);
288             queue.add(node);
289         }
290     }
291 public:
292     bool insert(TreeNode<T>* node)
293     {
294         return insert(node, ANY);
295     }
296 
297     virtual bool insert(TreeNode<T>* node, BTNodePos pos)
298     {
299         bool ret = true;
300 
301         if( node != NULL )
302         {
303             if( this->m_root == NULL )  //空树
304             {
305                 node->parent = NULL;
306                 this->m_root = node;
307             }
308             else
309             {
310                 BTreeNode<T>* np = find(node->parent);
311 
312                 if( np != NULL )
313                 {
314                     ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos);
315                 }
316                 else
317                 {
318                     THROW_EXCEPTION(InvalidParameterException, "invalid parent tree node...");
319                 }
320             }
321         }
322         else
323         {
324             THROW_EXCEPTION(InvalidParameterException, "parameter node can not be null...");
325         }
326 
327         return ret;
328     }
329 
330     bool insert(const T& value, TreeNode<T>* parent)
331     {
332         return insert(value, parent, ANY);
333     }
334 
335     virtual bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos)
336     {
337         bool ret = true;
338         BTreeNode<T>* node = BTreeNode<T>::NewNode();
339 
340         if( node == NULL )
341         {
342             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node...");
343         }
344         else
345         {
346             node->value = value;
347             node->parent = parent;
348 
349             ret = insert(node, pos);
350 
351             if( !ret )
352             {
353                 delete node;
354             }
355         }
356 
357         return ret;
358     }
359 
360     SharedPointer< Tree<T> > remove(TreeNode<T>* node) //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,//这样有机会对里面的元素做进一步操作
361     {
362         BTree<T>* ret = NULL;
363 
364         node = find(node);
365 
366         if( node == NULL )
367         {
368             THROW_EXCEPTION(InvalidParameterException, "parameter is invalid...");
369         }
370         else
371         {
372             remove(dynamic_cast<BTreeNode<T>*>(node), ret);
373 
374             m_queue.clear();
375         }
376 
377         return ret;
378     }
379 
380     SharedPointer< Tree<T> > remove(const T& value)
381     {
382         BTree<T>* ret = NULL;
383 
384         BTreeNode<T>* node = find(value);
385 
386         if( node == NULL )
387         {
388             THROW_EXCEPTION(InvalidParameterException, "can not find node via value...");
389         }
390         else
391         {
392             remove(node, ret);
393 
394             m_queue.clear();
395         }
396 
397         return ret;
398     }
399 
400     BTreeNode<T>* find(const T& value) const
401     {
402         return find(root(), value);
403     }
404 
405     BTreeNode<T>* find(TreeNode<T>* node) const
406     {
407         return find(root(), dynamic_cast<BTreeNode<T>*>(node));
408     }
409 
410     BTreeNode<T>* root() const
411     {
412         return dynamic_cast<BTreeNode<T>*>(this->m_root);
413     }
414 
415     int degree() const
416     {
417         return degree(root());
418     }
419 
420     int count() const
421     {
422         return count(root());
423     }
424 
425     int height() const
426     {
427         return height(root());
428     }
429 
430     void clear()
431     {
432         free(root());
433 
434         m_queue.clear();
435 
436         this->m_root = NULL;
437     }
438 
439     bool begin()
440     {
441         bool ret = ( root() != NULL );
442 
443         if( ret )
444         {
445             m_queue.clear();
446             m_queue.add(root());
447         }
448 
449         return ret;
450     }
451 
452     bool end()
453     {
454         return (m_queue.length() == 0);
455     }
456 
457     bool next()
458     {
459         bool ret = (m_queue.length() > 0);
460 
461         if( ret )
462         {
463             BTreeNode<T>* node = m_queue.front();
464 
465             m_queue.remove();  //将对头元素出队,相当于移动游标
466 
467             if( node->left != NULL )
468             {
469                 m_queue.add(node->left);
470             }
471 
472             if( node->right )
473             {
474                 m_queue.add(node->right);
475             }
476         }
477 
478         return ret;
479     }
480 
481     T current()
482     {
483         if( !end() )  //遍历的过程当中调用current函数才有意义
484         {
485             return m_queue.front()->value;
486         }
487         else
488         {
489             THROW_EXCEPTION(InvalidOperationException, "No value at current position...");
490         }
491     }
492 
493     SharedPointer< Array<T> > traversal(BTTraversal order)
494     {
495         DynamicArray<T>* ret = NULL;
496         LinkQueue<BTreeNode<T>*> queue;
497 
498         switch( order ){
499         case PreOrder:
500             preOrderTraversal(root(), queue);
501             break;
502         case InOrder:
503             inOrderTraversal(root(), queue);
504             break;
505         case PostOrder:
506             postOrderTraversal(root(), queue);
507             break;
508         default:
509             THROW_EXCEPTION(InvalidParameterException, "parameter is invalid...");
510             break;
511         }
512 
513         ret = new DynamicArray<T>(queue.length());
514         //遍历完将结果保存到动态数组中去
515         if( ret != NULL )
516         {
517             for(int i = 0; i < ret->length(); i++, queue.remove())
518             {
519                 ret->set(i, queue.front()->value);
520             }
521         }
522         else
523         {
524             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create array...");
525         }
526 
527         return ret;
528     }
529 
530     ~BTree()
531     {
532         clear();
533     }
534 };
535 
536 }
537 
538 #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     int a[] = {8, 9, 10, 11, 7};
44 
45     SharedPointer< Tree<int> > sp = bt.remove(3);
46 
47     for(int i = 0; i < 5; i++)
48     {
49         TreeNode<int>* node = bt.find(a[i]);
50 
51         while( node )
52         {
53             cout << node->value << " ";
54             node = node->parent;
55         }
56 
57         cout << endl;
58     }
59 
60 */
61     cout << endl;
62 
63     for(bt.begin(); !bt.end(); bt.next())
64     {
65         cout << bt.current() << " ";
66     }
67 
68     cout << endl;
69 
70     SharedPointer< Array<int> > sp = NULL;
71 
72     sp = bt.traversal(PostOrder);   //先序遍历
73 
74     for(int i = 0; i < (*sp).length(); i++)
75     {
76         cout << (*sp)[i] << " ";
77     }
78     cout << endl;
79 
80     return 0;
81 }

结果如下:

小结:

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