二叉树(使用C++模板)

CBinTree.hpp

  1 #include <iostream>
  2 #include <queue>
  3 #include <stack>
  4 
  5 template <typename T>
  6 class BinTree
  7 {
  8 private:
  9     // 树节点
 10     typedef struct BinTreeNode
 11     {
 12         T data;
 13         struct BinTreeNode* left;
 14         struct BinTreeNode* right;
 15     }Node;
 16     
 17     //
 18     typedef struct
 19     {
 20         T stop;
 21         Node* root;
 22     }Tree;
 23 
 24 private:
 25     Tree m_Tree;
 26 
 27 public:
 28     // 初始化树
 29     BinTree(T stop);
 30     BinTree();
 31     ~BinTree();
 32     
 33     // 创建树
 34     void Create(T* array, unsigned int nLength);
 35     
 36     // 先序遍历
 37     void Preorder();
 38     
 39     // 中序遍历
 40     void Inorder();
 41     
 42     // 后序遍历
 43     void Postorder();
 44     
 45     // 层次遍历
 46     void Levelorder();
 47     
 48     // 先序非递归遍历
 49     void preOrder();
 50     
 51     // 中序非递归遍历
 52     void inOrder();
 53     
 54     // 后序非递归遍历
 55     void postOrder();
 56     
 57     // 返回节点个数
 58     int Size();
 59     
 60     // 返回树的高度(层次)
 61     int Height();
 62     
 63     // 查找并修改
 64     bool Modify(T src, T dst);
 65     
 66     // 判断是否为空树
 67     bool isEmpty();
 68     
 69     // 拷贝树
 70     bool Copy(BinTree& tree);
 71     
 72     // 清除树
 73     void Clear();
 74 
 75     // 返回树根
 76     void* GetRoot();
 77 public:
 78     BinTree& operator=(BinTree& tree);
 79 private:
 80     void Create(Node* &node, T* &array, unsigned int nLength);
 81     void Preorder(Node* node);
 82     void Inorder(Node* node);
 83     void Postorder(Node* node);
 84     void Levelorder(Node* node);
 85     void preOrder(Node* node);
 86     void inOrder(Node* node);
 87     void postOrder(Node* node);
 88     int Size(Node* node);
 89     int Height(Node* node);
 90     bool Modify(Node* node, T src, T dst);
 91     bool Copy(Node* &dst, Node* src);
 92     void Clear(Node* &node);
 93 };
 94 
 95 template<typename T>
 96 inline BinTree<T>::BinTree()
 97 {
 98     memset(&m_Tree, 0, sizeof(m_Tree));
 99 }
100 
101 template<typename T>
102 inline BinTree<T>::~BinTree()
103 {
104     Clear();
105 }
106 
107 /* 初始化树 */
108 template<typename T>
109 inline BinTree<T>::BinTree(T stop)
110 {
111     m_Tree.root = nullptr;
112     m_Tree.stop = stop;
113 }
114 
115 /* 创建树 */
116 template<typename T>
117 inline void BinTree<T>::Create(T* array, unsigned int nLength)
118 {
119     Create(m_Tree.root, array, nLength);
120 }
121 
122 template<typename T>
123 inline void BinTree<T>::Create(Node* &node, T* &array, unsigned int nLength)
124 {
125     static int nLen = nLength;
126     static int nCnt = 0;
127     nCnt++;
128 
129     if (*array == m_Tree.stop) node = nullptr;
130     else
131     {
132         node = new Node;
133         if (nullptr == node) return;
134         node->data = *array;
135 
136         if (nCnt == nLen) return;
137 
138         Create(node->left, ++array, nLength);
139         Create(node->right, ++array, nLength);
140     }
141 }
142 
143 /* 先序遍历树 */
144 template<typename T>
145 inline void BinTree<T>::Preorder()
146 {
147     Preorder(m_Tree.root);
148 }
149 
150 template<typename T>
151 inline void BinTree<T>::Preorder(Node * node)
152 {
153     if (nullptr == node) return;
154 
155     std::cout << node->data;
156     if (nullptr != node->left) Preorder(node->left);
157     if (nullptr != node->right) Preorder(node->right);
158 }
159 
160 /* 中序遍历树 */
161 template<typename T>
162 inline void BinTree<T>::Inorder()
163 {
164     Inorder(m_Tree.root);
165 }
166 
167 template<typename T>
168 inline void BinTree<T>::Inorder(Node * node)
169 {
170     if (nullptr == node) return;
171 
172     if (nullptr != node->left) Inorder(node->left);
173     std::cout << node->data;
174     if (nullptr != node->right) Inorder(node->right);
175 }
176 
177 /* 后序遍历树 */
178 template<typename T>
179 inline void BinTree<T>::Postorder()
180 {
181     Postorder(m_Tree.root);
182 }
183 
184 template<typename T>
185 inline void BinTree<T>::Postorder(Node * node)
186 {
187     if (nullptr == node) return;
188 
189     if (nullptr != node->left) Postorder(node->left);
190     if (nullptr != node->right) Postorder(node->right);
191     std::cout << node->data;
192 }
193 
194 /* 层次遍历树 */
195 template<typename T>
196 inline void BinTree<T>::Levelorder()
197 {
198     Levelorder(m_Tree.root);
199 }
200 
201 template<typename T>
202 inline void BinTree<T>::Levelorder(Node * node)
203 {
204     if (nullptr == node) return;
205 
206     std::queue<Node*> Q;
207     Q.push(node);
208 
209     Node* p = nullptr;
210     while (!Q.empty())
211     {
212         p = Q.front();
213         std::cout << p->data;
214         Q.pop();
215 
216         if (nullptr != p->left) Q.push(p->left);
217         if (nullptr != p->right) Q.push(p->right);
218     }
219 
220     p = nullptr;
221 }
222 
223 /* 先序非递归遍历树 */
224 template<typename T>
225 inline void BinTree<T>::preOrder()
226 {
227     preOrder(m_Tree.root);
228 }
229 
230 template<typename T>
231 inline void BinTree<T>::preOrder(Node * node)
232 {
233     if (nullptr == node) return;
234 
235     std::stack<Node*> S;
236     S.push(node);
237 
238     Node* p = nullptr;
239     while (!S.empty())
240     {
241         p = S.top();
242         std::cout << p->data;
243         S.pop();
244 
245         if (nullptr != p->right) S.push(p->right);
246         if (nullptr != p->left) S.push(p->left);
247     }
248 
249     p = nullptr;
250 }
251 
252 /* 中序非递归遍历树 */
253 template<typename T>
254 inline void BinTree<T>::inOrder()
255 {
256     inOrder(m_Tree.root);
257 }
258 
259 template<typename T>
260 inline void BinTree<T>::inOrder(Node * node)
261 {
262     if (nullptr == node) return;
263 
264     std::stack<Node*> S;
265     S.push(node);
266 
267     Node* p = node;
268     Node* q = nullptr;
269     while (!S.empty())
270     {
271         while (nullptr != p && nullptr != p->left)
272         {
273             S.push(p->left);
274             p = p->left;
275         }
276 
277         q = S.top();
278         std::cout << q->data;
279         S.pop();
280 
281         if (nullptr != q->right)
282         {
283             S.push(q->right);
284             p = q->right;
285         }
286     }
287 
288     p = q = nullptr;
289 }
290 
291 /* 后序非递归遍历树 */
292 template<typename T>
293 inline void BinTree<T>::postOrder()
294 {
295     postOrder(m_Tree.root);
296 }
297 
298 template<typename T>
299 inline void BinTree<T>::postOrder(Node * node)
300 {
301     if (nullptr == node) return;
302 
303     typedef struct
304     {
305         Node* ptr;
306         bool  bFlag;
307     }FlagNode;
308     FlagNode fn = { 0 };
309 
310     std::stack<FlagNode> S;
311 
312     Node* p = node;
313     bool  bSign = true;
314     do
315     {
316         while (nullptr != p)
317         {
318             fn.ptr = p;
319             fn.bFlag = false;
320             S.push(fn);
321             p = p->left;
322         }
323 
324         bSign = true;
325 
326         while (bSign && !S.empty())
327         {
328             fn = S.top();
329             S.pop();
330 
331             // bFlag = false 表示节点还没有判断右节点
332             // bFlag = true  表示节点已经判断完右节点
333             if (false == fn.bFlag)       
334             {
335                 fn.bFlag = true;
336                 S.push(fn);
337                 p = fn.ptr->right;
338                 bSign = false;
339             }
340             else
341             {
342                 std::cout << fn.ptr->data;
343             }
344         }
345     } while (!S.empty());
346 
347     p = nullptr;
348 }
349 
350 /* 返回节点个数 */
351 template<typename T>
352 inline int BinTree<T>::Size()
353 {
354     return Size(m_Tree.root);
355 }
356 
357 template<typename T>
358 inline int BinTree<T>::Size(Node * node)
359 {
360     if (nullptr == node) return 0;
361 
362     return Size(node->left) + Size(node->right) + 1;
363 }
364 
365 /* 返回树的高度(层次) */
366 template<typename T>
367 inline int BinTree<T>::Height()
368 {
369     return Height(m_Tree.root);
370 }
371 
372 template<typename T>
373 inline int BinTree<T>::Height(Node * node)
374 {
375     if (nullptr == node) return 0;
376 
377     int left = 0;
378     int right = 0;
379 
380     left = Height(node->left);
381     right = Height(node->right);
382     if (left > right) return left + 1;
383     else
384     {
385         return right + 1;
386     }
387 }
388 
389 /* 查找并修改 */
390 template<typename T>
391 inline bool BinTree<T>::Modify(T src, T dst)
392 {
393     return Modify(m_Tree.root, src, dst);
394 }
395 
396 template<typename T>
397 inline bool BinTree<T>::Modify(Node * node, T src, T dst)
398 {
399     if (nullptr == node) return false;
400 
401     if (src == node->data)
402     {
403         node->data = dst;
404         return true;
405     }
406 
407     bool bRet = true;
408 
409     bRet = Modify(node->left, src, dst);
410     if (bRet) return true;
411     else
412     {
413         bRet = Modify(node->right, src, dst);
414     }
415 
416     return bRet;
417 }
418 
419 /* 判断是否为空树 */
420 template<typename T>
421 inline bool BinTree<T>::isEmpty()
422 {
423     if (nullptr == m_Tree.root) return true;
424 
425     return false;
426 }
427 
428 /* 拷贝树 */
429 template<typename T>
430 inline bool BinTree<T>::Copy(BinTree& tree)
431 {
432     if (tree.isEmpty()) return false;
433     if (!isEmpty()) Clear(m_Tree.root);
434 
435     return Copy(m_Tree.root, (Node*)tree.GetRoot());
436 }
437 
438 template<typename T>
439 inline bool BinTree<T>::Copy(Node* &dst, Node* src)
440 {
441     if (nullptr == src)
442     {
443         dst = nullptr;
444         return true;
445     }
446 
447     dst = new Node;
448     if (nullptr == dst) return false;
449     dst->data = src->data;
450 
451     bool bRet = true;
452     bRet = Copy(dst->left, src->left);
453     if (!bRet) return false;
454     else
455     {
456         bRet = Copy(dst->right, src->right);
457     }
458     return bRet;
459 }
460 
461 /* 清除树 */
462 template<typename T>
463 inline void BinTree<T>::Clear()
464 {
465     if (!isEmpty()) Clear(m_Tree.root);
466 }
467 
468 template<typename T>
469 inline void BinTree<T>::Clear(Node* &node)
470 {
471     if (nullptr == node) return;
472 
473     Clear(node->left);
474     Clear(node->right);
475     delete node;
476 
477     node = nullptr;
478 }
479 
480 /* 返回树根 */
481 template<typename T>
482 inline void * BinTree<T>::GetRoot()
483 {
484     return m_Tree.root;
485 }
486 
487 template<typename T>
488 inline BinTree<T> & BinTree<T>::operator=(BinTree & tree)
489 {
490     Copy(tree);
491 
492     return *this;
493 }

main.cpp

 1 #include "CBinTree.hpp"
 2 
 3 int main()
 4 {
 5     char str[] = "ABC##DE##F##G#H##";
 6     int nStrLen = strlen(str);
 7 
 8     BinTree<char> CharTree('#');
 9     CharTree.Create(str, nStrLen);
10     CharTree.Preorder();
11     puts("");
12 
13     BinTree<char> CharCopy;
14     CharCopy = CharTree;
15     //CharCopy.Copy(CharTree);
16     CharCopy.Preorder();
17     puts("");
18 
19 //////////////////////////////////////////////////////////////////
20     int array[] = { 1,2,3,9,9,4,5,9,9,6,9,9,7,9,8,9,9 };
21     int nIntLen = sizeof(array) / sizeof(int);
22 
23     BinTree<int> IntTree(9);
24     IntTree.Create(array, nIntLen);
25     IntTree.Preorder();
26     puts("");
27 
28     BinTree<int> IntCopy;
29     IntCopy = IntTree;
30     //IntCopy.Copy(IntTree);
31     IntCopy.Preorder();
32     puts("");
33 
34     system("pause");
35     return 0;
36 }

 

posted @ 2021-09-10 14:34  HyperVS  阅读(229)  评论(0)    收藏  举报