第五十七课 树中属性操作的实现

Posted wanmeishenghuo

tags:

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

技术分享图片

 

技术分享图片

 

添加count函数:

  1 #ifndef GTREE_H
  2 #define GTREE_H
  3 
  4 #include "Tree.h"
  5 #include "GTreeNode.h"
  6 #include "Exception.h"
  7 
  8 namespace DTLib
  9 {
 10 
 11 template < typename T >
 12 class GTree : public Tree<T>
 13 {
 14 protected:
 15     GTreeNode<T>* find(GTreeNode<T>* node, const T& value) const
 16     {
 17         GTreeNode<T>* ret = NULL;
 18 
 19         if( node != NULL )
 20         {
 21             if( node->value == value )
 22             {
 23                 return node;
 24             }
 25             else
 26             {
 27                 for(node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
 28                 {
 29                     ret = find(node->child.current(), value);
 30                 }
 31             }
 32         }
 33 
 34         return ret;
 35     }
 36 
 37     GTreeNode<T>* find(GTreeNode<T>* node,  GTreeNode<T>* obj) const
 38     {
 39         GTreeNode<T>* ret = NULL;
 40 
 41         if( node == obj )
 42         {
 43             return node;
 44         }
 45         else
 46         {
 47             if( node != NULL )
 48             {
 49                 for( node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
 50                 {
 51                     ret = find(node->child.current(), obj);
 52                 }
 53             }
 54         }
 55 
 56         return ret;
 57     }
 58 
 59     void free(GTreeNode<T>* node)
 60     {
 61         if( node != NULL )
 62         {
 63             for(node->child.move(0); !node->child.end(); node->child.next())
 64             {
 65                 free(node->child.current());
 66             }
 67 
 68             if( node->flag() )
 69             {
 70                 delete node;
 71             }
 72         }
 73     }
 74 
 75     void remove(GTreeNode<T>* node, GTree<T>*& ret)
 76     {
 77         ret = new GTree<T>();
 78 
 79         if( ret == NULL )
 80         {
 81             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create tree...");
 82         }
 83         else
 84         {
 85             if( root() == node )
 86             {
 87                 this->m_root = NULL;
 88             }
 89             else
 90             {
 91                 LinkList<GTreeNode<T>*>& child = dynamic_cast<GTreeNode<T>*>(node->parent)->child;
 92 
 93                 child.remove(child.find(node));
 94 
 95                 node->parent = NULL;
 96             }
 97 
 98             ret->m_root = node;
 99         }
100     }
101 
102     int count(GTreeNode<T>* node) const
103     {
104         int ret = 0;
105 
106         if( node != NULL )
107         {
108             ret = 1;
109 
110             //node如果没有孩子,则for不执行
111             for(node->child.move(0); !node->child.end(); node->child.next())
112             {
113                 ret += count(node->child.current());
114             }
115         }
116 
117         return ret;
118     }
119 public:
120     bool insert(TreeNode<T>* node)
121     {
122         bool ret = true;
123 
124         if( node != NULL )
125         {
126             if( this->m_root == NULL ) //如果待插入节点的父节点为空,则这个节点将为根节点
127             {
128                 node->parent = NULL;
129                 this->m_root = node;
130             }
131             else
132             {
133                 GTreeNode<T>* np = find(node->parent);
134 
135                 if( np != NULL )
136                 {
137                     GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
138 
139                     if( np->child.find(n) < 0 )
140                     {
141                         np->child.insert(n);
142                     }
143                 }
144                 else
145                 {
146                     THROW_EXCEPTION(InvalidParameterException, "Invalid parent tree node...");
147                 }
148             }
149         }
150         else
151         {
152             THROW_EXCEPTION(InvalidParameterException, "Parameter node cannot be NULL ...");
153         }
154 
155         return ret;
156     }
157 
158     bool insert(const T& value, TreeNode<T>* parent)
159     {
160         bool ret = true;
161 
162         GTreeNode<T>* node = GTreeNode<T>::NewNode();
163 
164         if( node != NULL )
165         {
166             node->value = value;
167             node->parent = parent;
168 
169             insert(node);
170         }
171         else
172         {
173             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node ...");
174         }
175 
176         return ret;
177     }
178 
179     //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,这样有机会对里面的元素做进一步操作
180     SharedPointer< Tree<T> > remove(const T& value)
181     {
182         GTree<T>* ret = NULL;
183 
184         GTreeNode<T>* node = find(value);
185 
186         if( node == NULL )
187         {
188             THROW_EXCEPTION(InvalidParameterException, "can not find the node ...");
189         }
190         else
191         {
192             remove(node, ret);
193         }
194 
195         return ret;
196     }
197 
198     SharedPointer< Tree<T> > remove(TreeNode<T>* node)
199     {
200         GTree<T>* ret = NULL;
201 
202         node = find(node);
203 
204         if( node == NULL )
205         {
206             THROW_EXCEPTION(InvalidParameterException, "parameter node is invalid ...");
207         }
208         else
209         {
210             remove(dynamic_cast<GTreeNode<T>*>(node), ret);
211         }
212 
213         return ret;
214     }
215 
216     GTreeNode<T>* find(const T& value) const  // 返回GTreeNode,赋值兼容性
217     {
218         return find(root(), value);
219     }
220 
221     GTreeNode<T>* find(TreeNode<T>* node) const
222     {
223         return find(root(), dynamic_cast<GTreeNode<T>*>(node));
224     }
225 
226     GTreeNode<T>* root() const
227     {
228         return dynamic_cast<GTreeNode<T>*>(this->m_root);
229     }
230 
231     int degree() const
232     {
233         return 0;
234     }
235     int count() const
236     {
237         return count(root());
238     }
239 
240     int height() const
241     {
242         return 0;
243     }
244 
245     void clear()
246     {
247         free(root());
248 
249         this->m_root = NULL;
250     }
251 
252     ~GTree()
253     {
254         clear();
255     }
256 };
257 
258 }
259 
260 #endif // GTREE_H

测试程序如下:

 1 #include <iostream>
 2 #include "GTree.h"
 3 #include "GTreeNode.h"
 4 
 5 
 6 using namespace std;
 7 using namespace DTLib;
 8 
 9 
10 int main()
11 {
12     GTree<char> t;
13     GTreeNode<char>* node = NULL;
14     GTreeNode<char> root;
15 
16     root.value = A;
17     root.parent = NULL;
18 
19     t.insert(&root);
20 
21     node = t.find(A);
22     t.insert(B, node);
23     t.insert(C, node);
24     t.insert(D, node);
25 
26     node = t.find(B);
27     t.insert(E, node);
28     t.insert(F, node);
29 
30     node = t.find(E);
31     t.insert(K, node);
32     t.insert(L, node);
33 
34     node = t.find(C);
35     t.insert(G, node);
36 
37     node = t.find(D);
38     t.insert(H, node);
39     t.insert(I, node);
40     t.insert(J, node);
41 
42     node = t.find(H);
43     t.insert(M, node);
44 
45     cout << t.count() << endl;
46 
47 
48     return 0;
49 }

结果如下:

技术分享图片

 

 

 

 

技术分享图片

 

技术分享图片

 

 

技术分享图片

 

技术分享图片

 

添加求高度和度数的函数:

  1 #ifndef GTREE_H
  2 #define GTREE_H
  3 
  4 #include "Tree.h"
  5 #include "GTreeNode.h"
  6 #include "Exception.h"
  7 
  8 namespace DTLib
  9 {
 10 
 11 template < typename T >
 12 class GTree : public Tree<T>
 13 {
 14 protected:
 15     GTreeNode<T>* find(GTreeNode<T>* node, const T& value) const
 16     {
 17         GTreeNode<T>* ret = NULL;
 18 
 19         if( node != NULL )
 20         {
 21             if( node->value == value )
 22             {
 23                 return node;
 24             }
 25             else
 26             {
 27                 for(node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
 28                 {
 29                     ret = find(node->child.current(), value);
 30                 }
 31             }
 32         }
 33 
 34         return ret;
 35     }
 36 
 37     GTreeNode<T>* find(GTreeNode<T>* node,  GTreeNode<T>* obj) const
 38     {
 39         GTreeNode<T>* ret = NULL;
 40 
 41         if( node == obj )
 42         {
 43             return node;
 44         }
 45         else
 46         {
 47             if( node != NULL )
 48             {
 49                 for( node->child.move(0); !node->child.end() && (ret == NULL); node->child.next())
 50                 {
 51                     ret = find(node->child.current(), obj);
 52                 }
 53             }
 54         }
 55 
 56         return ret;
 57     }
 58 
 59     void free(GTreeNode<T>* node)
 60     {
 61         if( node != NULL )
 62         {
 63             for(node->child.move(0); !node->child.end(); node->child.next())
 64             {
 65                 free(node->child.current());
 66             }
 67 
 68             if( node->flag() )
 69             {
 70                 delete node;
 71             }
 72         }
 73     }
 74 
 75     void remove(GTreeNode<T>* node, GTree<T>*& ret)
 76     {
 77         ret = new GTree<T>();
 78 
 79         if( ret == NULL )
 80         {
 81             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create tree...");
 82         }
 83         else
 84         {
 85             if( root() == node )
 86             {
 87                 this->m_root = NULL;
 88             }
 89             else
 90             {
 91                 LinkList<GTreeNode<T>*>& child = dynamic_cast<GTreeNode<T>*>(node->parent)->child;
 92 
 93                 child.remove(child.find(node));
 94 
 95                 node->parent = NULL;
 96             }
 97 
 98             ret->m_root = node;
 99         }
100     }
101 
102     int count(GTreeNode<T>* node) const
103     {
104         int ret = 0;
105 
106         if( node != NULL )
107         {
108             ret = 1;
109 
110             //node如果没有孩子,则for不执行
111             for(node->child.move(0); !node->child.end(); node->child.next())
112             {
113                 ret += count(node->child.current());
114             }
115         }
116 
117         return ret;
118     }
119 
120     int height(GTreeNode<T>* node) const
121     {
122         int ret = 0;
123 
124         if( node != NULL )
125         {
126             for(node->child.move(0); !node->child.end(); node->child.next())
127             {
128                 int h = height(node->child.current());
129 
130                 if( ret < h )
131                 {
132                     ret = h;
133                 }
134             }
135 
136             ret = ret + 1;
137         }
138 
139         return ret;
140     }
141 
142     int degree(GTreeNode<T>* node) const
143     {
144         int ret = 0;
145 
146         if( node != NULL )
147         {
148             ret = node->child.length();  //根节点的度数
149 
150             for(node->child.move(0); !node->child.end(); node->child.next())
151             {
152                 int d = degree(node->child.current());
153 
154                 if( ret < d )
155                 {
156                     ret = d;
157                 }
158             }
159         }
160 
161         return ret;
162     }
163 public:
164     bool insert(TreeNode<T>* node)
165     {
166         bool ret = true;
167 
168         if( node != NULL )
169         {
170             if( this->m_root == NULL ) //如果待插入节点的父节点为空,则这个节点将为根节点
171             {
172                 node->parent = NULL;
173                 this->m_root = node;
174             }
175             else
176             {
177                 GTreeNode<T>* np = find(node->parent);
178 
179                 if( np != NULL )
180                 {
181                     GTreeNode<T>* n = dynamic_cast<GTreeNode<T>*>(node);
182 
183                     if( np->child.find(n) < 0 )
184                     {
185                         np->child.insert(n);
186                     }
187                 }
188                 else
189                 {
190                     THROW_EXCEPTION(InvalidParameterException, "Invalid parent tree node...");
191                 }
192             }
193         }
194         else
195         {
196             THROW_EXCEPTION(InvalidParameterException, "Parameter node cannot be NULL ...");
197         }
198 
199         return ret;
200     }
201 
202     bool insert(const T& value, TreeNode<T>* parent)
203     {
204         bool ret = true;
205 
206         GTreeNode<T>* node = GTreeNode<T>::NewNode();
207 
208         if( node != NULL )
209         {
210             node->value = value;
211             node->parent = parent;
212 
213             insert(node);
214         }
215         else
216         {
217             THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node ...");
218         }
219 
220         return ret;
221     }
222 
223     //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,这样有机会对里面的元素做进一步操作
224     SharedPointer< Tree<T> > remove(const T& value)
225     {
226         GTree<T>* ret = NULL;
227 
228         GTreeNode<T>* node = find(value);
229 
230         if( node == NULL )
231         {
232             THROW_EXCEPTION(InvalidParameterException, "can not find the node ...");
233         }
234         else
235         {
236             remove(node, ret);
237         }
238 
239         return ret;
240     }
241 
242     SharedPointer< Tree<T> > remove(TreeNode<T>* node)
243     {
244         GTree<T>* ret = NULL;
245 
246         node = find(node);
247 
248         if( node == NULL )
249         {
250             THROW_EXCEPTION(InvalidParameterException, "parameter node is invalid ...");
251         }
252         else
253         {
254             remove(dynamic_cast<GTreeNode<T>*>(node), ret);
255         }
256 
257         return ret;
258     }
259 
260     GTreeNode<T>* find(const T& value) const  // 返回GTreeNode,赋值兼容性
261     {
262         return find(root(), value);
263     }
264 
265     GTreeNode<T>* find(TreeNode<T>* node) const
266     {
267         return find(root(), dynamic_cast<GTreeNode<T>*>(node));
268     }
269 
270     GTreeNode<T>* root() const
271     {
272         return dynamic_cast<GTreeNode<T>*>(this->m_root);
273     }
274 
275     int degree() const
276     {
277         return degree(root());
278     }
279     int count() const
280     {
281         return count(root());
282     }
283 
284     int height() const
285     {
286         return height(root());
287     }
288 
289     void clear()
290     {
291         free(root());
292 
293         this->m_root = NULL;
294     }
295 
296     ~GTree()
297     {
298         clear();
299     }
300 };
301 
302 }
303 
304 #endif // GTREE_H

 

技术分享图片

 

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

python五十七课——正则表达式(多个字符)

第五十四课 树中节点的插入操作

第五十七天

第五十五课 树中节点的清除操作

第五十六课 树中结点的删除操作

第五十三课 树中节点的查找操作