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