第六十五课 二叉树中属性操作的实现

Posted wanmeishenghuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第六十五课 二叉树中属性操作的实现相关的知识,希望对你有一定的参考价值。

技术分享图片

 

技术分享图片

 

递归功能函数:

1 int count(BTreeNode<T>* node) const
2     {
3         return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0;
4     }

 

技术分享图片

 

功能函数如下:

 1 int height(BTreeNode<T>* node) const
 2     {
 3         int ret = 0;
 4 
 5         if( node != NULL )
 6         {
 7             int lh = height(node->left);
 8             int rh = height(node->right);
 9 
10             ret = ((lh > rh) ? lh : rh) + 1;;
11         }
12 
13         return ret;
14     }

 

技术分享图片

 

degree的递归功能函数如下:

 1 int degree(BTreeNode<T>* node) const
 2     {
 3         int ret = 0;
 4 
 5         if( node != NULL )
 6         {
 7             BTreeNode<T>* child[] = {node->left, node->right};
 8 
 9             ret = (!!node->left + !!node->right);
10 
11             for( int i = 0; (i < 2) && (ret < 2); i++)
12             {
13                 int d = degree(child[i]);
14 
15                 if( ret < d )
16                 {
17                     ret = d;
18                 }
19             }
20         }
21 
22         return ret;
23     }

我们去掉了冗余代码,用数组和for循环的方式实现。 如果不用这个方式,将会出现两段相似的代码。

如下:

 1 #if 0
 2     int degree(BTreeNode<T>* node) const
 3     {
 4         int ret = 0;
 5 
 6         if( node != NULL )
 7         {
 8             int dl = degree(node->left);
 9             int dr = degree(node->right);
10 
11             ret = (!!node->left + !!node->right);
12 
13             if( ret < dl )
14             {
15                 ret = dl;
16             }
17 
18             if( ret < dr )
19             {
20                 ret = dr;
21             }
22         }
23 
24         return ret;
25     }
26 #endif

 

总的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 
  9 
 10 namespace DTLib
 11 {
 12 
 13 template < typename T >
 14 class BTree : public Tree<T>
 15 {
 16 protected:
 17     //定义递归功能函数
 18     virtual BTreeNode<T>* find(BTreeNode<T>* node, const T& value) const
 19     {
 20         BTreeNode<T>* ret = NULL;
 21 
 22         if( node != NULL )
 23         {
 24             if( node->value == value )
 25             {
 26                 ret = node;
 27             }
 28             else
 29             {
 30                 if( ret == NULL )
 31                 {
 32                     ret = find(node->left, value);
 33                 }
 34 
 35                 if( ret == NULL )
 36                 {
 37                     ret = find(node->right, value);
 38                 }
 39             }
 40         }
 41 
 42         return ret;
 43     }
 44 
 45     virtual BTreeNode<T>* find(BTreeNode<T>* node, BTreeNode<T>* obj) const
 46     {
 47         BTreeNode<T>* ret = NULL;
 48 
 49         if( node == obj )
 50         {
 51             ret = node;
 52         }
 53         else
 54         {
 55             if( node != NULL )
 56             {
 57                 if( ret == NULL )
 58                 {
 59                     ret = find(node->left, obj);
 60                 }
 61 
 62                 if( ret == NULL )
 63                 {
 64                     ret = find(node->right, obj);
 65                 }
 66             }
 67         }
 68 
 69         return ret;
 70     }
 71 
 72     virtual bool insert(BTreeNode<T>* n, BTreeNode<T>* np, BTNodePos pos)
 73     {
 74         bool ret = true;
 75 
 76         if( pos == ANY )
 77         {
 78             if( np->left == NULL )
 79             {
 80                 np->left = n;
 81             }
 82             else if( np->right == NULL )
 83             {
 84                 np->right = n;
 85             }
 86             else
 87             {
 88                 ret = false;
 89             }
 90         }
 91         else if( pos == LEFT )
 92         {
 93             if( np->left == NULL )
 94             {
 95                 np->left = n;
 96             }
 97             else
 98             {
 99                 ret = false;
100             }
101         }
102         else if( pos == RIGHT )
103         {
104             if( np->right == NULL )
105             {
106                 np->right = n;
107             }
108             else
109             {
110                 ret = false;
111             }
112         }
113         else
114         {
115             ret = false;
116         }
117 
118         return ret;
119     }
120 
121     virtual void remove(BTreeNode<T>* node, BTree<T>*& ret)
122     {
123         ret = new BTree<T>();
124 
125         if( ret == NULL )
126         {
127             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create btree...");
128         }
129         else
130         {
131             if( root() == node )
132             {
133                 this->m_root = NULL;
134             }
135             else
136             {
137                 BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent);
138 
139                 if( parent->left == node )
140                 {
141                     parent->left = NULL;
142                 }
143                 else if( parent->right == node )
144                 {
145                     parent->right = NULL;
146                 }
147 
148                 node->parent = NULL;
149             }
150 
151             ret->m_root = node;  //作为子树返回
152         }
153     }
154 
155     virtual void free(BTreeNode<T>* node)
156     {
157         if( node != NULL )
158         {
159             free(node->left);
160             free(node->right);
161 
162             if( node->flag() )
163             {
164                 delete node;
165             }
166         }
167     }
168     #if 0
169     int count(BTreeNode<T>* node) const
170     {
171         int ret = 0;
172 
173         if( node != NULL )
174         {
175             ret = count(node->left) + count(node->right) + 1;
176         }
177 
178         return ret;
179     }
180     #endif
181 
182     int count(BTreeNode<T>* node) const
183     {
184         return (node != NULL) ? (count(node->left) + count(node->right) + 1) : 0;
185     }
186 
187     int height(BTreeNode<T>* node) const
188     {
189         int ret = 0;
190 
191         if( node != NULL )
192         {
193             int lh = height(node->left);
194             int rh = height(node->right);
195 
196             ret = ((lh > rh) ? lh : rh) + 1;;
197         }
198 
199         return ret;
200     }
201 
202 #if 0
203     int degree(BTreeNode<T>* node) const
204     {
205         int ret = 0;
206 
207         if( node != NULL )
208         {
209             int dl = degree(node->left);
210             int dr = degree(node->right);
211 
212             ret = (!!node->left + !!node->right);
213 
214             if( ret < dl )
215             {
216                 ret = dl;
217             }
218 
219             if( ret < dr )
220             {
221                 ret = dr;
222             }
223         }
224 
225         return ret;
226     }
227 #endif
228 //二叉树的最大度数为2,上面的实现效率太低
229     int degree(BTreeNode<T>* node) const
230     {
231         int ret = 0;
232 
233         if( node != NULL )
234         {
235             BTreeNode<T>* child[] = {node->left, node->right};
236 
237             ret = (!!node->left + !!node->right);
238 
239             for( int i = 0; (i < 2) && (ret < 2); i++)
240             {
241                 int d = degree(child[i]);
242 
243                 if( ret < d )
244                 {
245                     ret = d;
246                 }
247             }
248         }
249 
250         return ret;
251     }
252 public:
253     bool insert(TreeNode<T>* node)
254     {
255         return insert(node, ANY);
256     }
257 
258     virtual bool insert(TreeNode<T>* node, BTNodePos pos)
259     {
260         bool ret = true;
261 
262         if( node != NULL )
263         {
264             if( this->m_root == NULL )  //空树
265             {
266                 node->parent = NULL;
267                 this->m_root = node;
268             }
269             else
270             {
271                 BTreeNode<T>* np = find(node->parent);
272 
273                 if( np != NULL )
274                 {
275                     ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos);
276                 }
277                 else
278                 {
279                     THROW_EXCEPTION(InvalidParameterException, "invalid parent tree node...");
280                 }
281             }
282         }
283         else
284         {
285             THROW_EXCEPTION(InvalidParameterException, "parameter node can not be null...");
286         }
287 
288         return ret;
289     }
290 
291     bool insert(const T& value, TreeNode<T>* parent)
292     {
293         return insert(value, parent, ANY);
294     }
295 
296     virtual bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos)
297     {
298         bool ret = true;
299         BTreeNode<T>* node = BTreeNode<T>::NewNode();
300 
301         if( node == NULL )
302         {
303             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node...");
304         }
305         else
306         {
307             node->value = value;
308             node->parent = parent;
309 
310             ret = insert(node, pos);
311 
312             if( !ret )
313             {
314                 delete node;
315             }
316         }
317 
318         return ret;
319     }
320 
321     SharedPointer< Tree<T> > remove(TreeNode<T>* node) //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,//这样有机会对里面的元素做进一步操作
322     {
323         BTree<T>* ret = NULL;
324 
325         node = find(node);
326 
327         if( node == NULL )
328         {
329             THROW_EXCEPTION(InvalidParameterException, "parameter is invalid...");
330         }
331         else
332         {
333             remove(dynamic_cast<BTreeNode<T>*>(node), ret);
334         }
335 
336         return ret;
337     }
338 
339     SharedPointer< Tree<T> > remove(const T& value)
340     {
341         BTree<T>* ret = NULL;
342 
343         BTreeNode<T>* node = find(value);
344 
345         if( node == NULL )
346         {
347             THROW_EXCEPTION(InvalidParameterException, "can not find node via value...");
348         }
349         else
350         {
351             remove(node, ret);
352         }
353 
354         return ret;
355     }
356 
357     BTreeNode<T>* find(const T& value) const
358     {
359         return find(root(), value);
360     }
361 
362     BTreeNode<T>* find(TreeNode<T>* node) const
363     {
364         return find(root(), dynamic_cast<BTreeNode<T>*>(node));
365     }
366 
367     BTreeNode<T>* root() const
368     {
369         return dynamic_cast<BTreeNode<T>*>(this->m_root);
370     }
371 
372     int degree() const
373     {
374         return degree(root());
375     }
376 
377     int count() const
378     {
379         return count(root());
380     }
381 
382     int height() const
383     {
384         return height(root());
385     }
386 
387     void clear()
388     {
389         free(root());
390 
391         this->m_root = NULL;
392     }
393 
394     ~BTree()
395     {
396         clear();
397     }
398 };
399 
400 }
401 
402 #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     return 0;
62 }

结果如下:

技术分享图片

 

 

 

技术分享图片

 

以上是关于第六十五课 二叉树中属性操作的实现的主要内容,如果未能解决你的问题,请参考以下文章

第六十四课 二叉树中结点的删除与清除

JAVA学习第六十五课 — 正則表達式

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

数据结构开发(24):二叉树中属性操作层次遍历与典型遍历

第六十课 二叉树的深层特性

剑指Offer(Java版)第六十五题:给定一棵二叉搜索树,请找出其中的第k小的结点。 例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。