第六十四课 二叉树中结点的删除与清除
Posted wanmeishenghuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第六十四课 二叉树中结点的删除与清除相关的知识,希望对你有一定的参考价值。
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 namespace DTLib 10 { 11 12 template < typename T > 13 class BTree : public Tree<T> 14 { 15 protected: 16 //定义递归功能函数 17 virtual BTreeNode<T>* find(BTreeNode<T>* node, const T& value) const 18 { 19 BTreeNode<T>* ret = NULL; 20 21 if( node != NULL ) 22 { 23 if( node->value == value ) 24 { 25 ret = node; 26 } 27 else 28 { 29 if( ret == NULL ) 30 { 31 ret = find(node->left, value); 32 } 33 34 if( ret == NULL ) 35 { 36 ret = find(node->right, value); 37 } 38 } 39 } 40 41 return ret; 42 } 43 44 virtual BTreeNode<T>* find(BTreeNode<T>* node, BTreeNode<T>* obj) const 45 { 46 BTreeNode<T>* ret = NULL; 47 48 if( node == obj ) 49 { 50 ret = node; 51 } 52 else 53 { 54 if( node != NULL ) 55 { 56 if( ret == NULL ) 57 { 58 ret = find(node->left, obj); 59 } 60 61 if( ret == NULL ) 62 { 63 ret = find(node->right, obj); 64 } 65 } 66 } 67 68 return ret; 69 } 70 71 virtual bool insert(BTreeNode<T>* n, BTreeNode<T>* np, BTNodePos pos) 72 { 73 bool ret = true; 74 75 if( pos == ANY ) 76 { 77 if( np->left == NULL ) 78 { 79 np->left = n; 80 } 81 else if( np->right == NULL ) 82 { 83 np->right = n; 84 } 85 else 86 { 87 ret = false; 88 } 89 } 90 else if( pos == LEFT ) 91 { 92 if( np->left == NULL ) 93 { 94 np->left = n; 95 } 96 else 97 { 98 ret = false; 99 } 100 } 101 else if( pos == RIGHT ) 102 { 103 if( np->right == NULL ) 104 { 105 np->right = n; 106 } 107 else 108 { 109 ret = false; 110 } 111 } 112 else 113 { 114 ret = false; 115 } 116 117 return ret; 118 } 119 120 virtual void remove(BTreeNode<T>* node, BTree<T>*& ret) 121 { 122 ret = new BTree<T>(); 123 124 if( ret == NULL ) 125 { 126 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create btree..."); 127 } 128 else 129 { 130 if( root() == node ) 131 { 132 this->m_root = NULL; 133 } 134 else 135 { 136 BTreeNode<T>* parent = dynamic_cast<BTreeNode<T>*>(node->parent); 137 138 if( parent->left == node ) 139 { 140 parent->left = NULL; 141 } 142 else if( parent->right == node ) 143 { 144 parent->right = NULL; 145 } 146 147 node->parent = NULL; 148 } 149 150 ret->m_root = node; //作为子树返回 151 } 152 } 153 public: 154 bool insert(TreeNode<T>* node) 155 { 156 return insert(node, ANY); 157 } 158 159 virtual bool insert(TreeNode<T>* node, BTNodePos pos) 160 { 161 bool ret = true; 162 163 if( node != NULL ) 164 { 165 if( this->m_root == NULL ) //空树 166 { 167 node->parent = NULL; 168 this->m_root = node; 169 } 170 else 171 { 172 BTreeNode<T>* np = find(node->parent); 173 174 if( np != NULL ) 175 { 176 ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos); 177 } 178 else 179 { 180 THROW_EXCEPTION(InvalidParameterException, "invalid parent tree node..."); 181 } 182 } 183 } 184 else 185 { 186 THROW_EXCEPTION(InvalidParameterException, "parameter node can not be null..."); 187 } 188 189 return ret; 190 } 191 192 bool insert(const T& value, TreeNode<T>* parent) 193 { 194 return insert(value, parent, ANY); 195 } 196 197 virtual bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos) 198 { 199 bool ret = true; 200 BTreeNode<T>* node = BTreeNode<T>::NewNode(); 201 202 if( node == NULL ) 203 { 204 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node..."); 205 } 206 else 207 { 208 node->value = value; 209 node->parent = parent; 210 211 ret = insert(node, pos); 212 213 if( !ret ) 214 { 215 delete node; 216 } 217 } 218 219 return ret; 220 } 221 222 SharedPointer< Tree<T> > remove(TreeNode<T>* node) //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,//这样有机会对里面的元素做进一步操作 223 { 224 BTree<T>* ret = NULL; 225 226 node = find(node); 227 228 if( node == NULL ) 229 { 230 THROW_EXCEPTION(InvalidParameterException, "parameter is invalid..."); 231 } 232 else 233 { 234 remove(dynamic_cast<BTreeNode<T>*>(node), ret); 235 } 236 237 return ret; 238 } 239 240 SharedPointer< Tree<T> > remove(const T& value) 241 { 242 BTree<T>* ret = NULL; 243 244 BTreeNode<T>* node = find(value); 245 246 if( node == NULL ) 247 { 248 THROW_EXCEPTION(InvalidParameterException, "can not find node via value..."); 249 } 250 else 251 { 252 remove(node, ret); 253 } 254 255 return ret; 256 } 257 258 BTreeNode<T>* find(const T& value) const 259 { 260 return find(root(), value); 261 } 262 263 BTreeNode<T>* find(TreeNode<T>* node) const 264 { 265 return find(root(), dynamic_cast<BTreeNode<T>*>(node)); 266 } 267 268 BTreeNode<T>* root() const 269 { 270 return dynamic_cast<BTreeNode<T>*>(this->m_root); 271 } 272 273 int degree() const 274 { 275 return 0; 276 } 277 278 int count() const 279 { 280 return 0; 281 } 282 283 int height() const 284 { 285 return 0; 286 } 287 288 void clear() 289 { 290 this->m_root = NULL; 291 } 292 293 ~BTree() 294 { 295 clear(); 296 } 297 }; 298 299 } 300 301 #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 n = bt.find(6); 39 bt.insert(11, n, LEFT); 40 41 int a[] = {8, 9, 10, 11, 7}; 42 43 SharedPointer< Tree<int> > sp = bt.remove(3); 44 45 for(int i = 0; i < 5; i++) 46 { 47 TreeNode<int>* node = bt.find(a[i]); 48 49 while( node ) 50 { 51 cout << node->value << " "; 52 node = node->parent; 53 } 54 55 cout << endl; 56 } 57 58 for(int i = 0; i < 5; i++) 59 { 60 TreeNode<int>* node = sp->find(a[i]); 61 62 while( node ) 63 { 64 cout << node->value << " "; 65 node = node->parent; 66 } 67 68 cout << endl; 69 } 70 71 return 0; 72 }
结果如下:
添加清除操作:
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 public: 169 bool insert(TreeNode<T>* node) 170 { 171 return insert(node, ANY); 172 } 173 174 virtual bool insert(TreeNode<T>* node, BTNodePos pos) 175 { 176 bool ret = true; 177 178 if( node != NULL ) 179 { 180 if( this->m_root == NULL ) //空树 181 { 182 node->parent = NULL; 183 this->m_root = node; 184 } 185 else 186 { 187 BTreeNode<T>* np = find(node->parent); 188 189 if( np != NULL ) 190 { 191 ret = insert(dynamic_cast<BTreeNode<T>*>(node), np, pos); 192 } 193 else 194 { 195 THROW_EXCEPTION(InvalidParameterException, "invalid parent tree node..."); 196 } 197 } 198 } 199 else 200 { 201 THROW_EXCEPTION(InvalidParameterException, "parameter node can not be null..."); 202 } 203 204 return ret; 205 } 206 207 bool insert(const T& value, TreeNode<T>* parent) 208 { 209 return insert(value, parent, ANY); 210 } 211 212 virtual bool insert(const T& value, TreeNode<T>* parent, BTNodePos pos) 213 { 214 bool ret = true; 215 BTreeNode<T>* node = BTreeNode<T>::NewNode(); 216 217 if( node == NULL ) 218 { 219 THROW_EXCEPTION(NoEnoughMemoryException, "No memory to create node..."); 220 } 221 else 222 { 223 node->value = value; 224 node->parent = parent; 225 226 ret = insert(node, pos); 227 228 if( !ret ) 229 { 230 delete node; 231 } 232 } 233 234 return ret; 235 } 236 237 SharedPointer< Tree<T> > remove(TreeNode<T>* node) //删除的节点的子节点我们还需要处理,因此要返回删除节点的指针,//这样有机会对里面的元素做进一步操作 238 { 239 BTree<T>* ret = NULL; 240 241 node = find(node); 242 243 if( node == NULL ) 244 { 245 THROW_EXCEPTION(InvalidParameterException, "parameter is invalid..."); 246 } 247 else 248 { 249 remove(dynamic_cast<BTreeNode<T>*>(node), ret); 250 } 251 252 return ret; 253 } 254 255 SharedPointer< Tree<T> > remove(const T& value) 256 { 257 BTree<T>* ret = NULL; 258 259 BTreeNode<T>* node = find(value); 260 261 if( node == NULL ) 262 { 263 THROW_EXCEPTION(InvalidParameterException, "can not find node via value..."); 264 } 265 else 266 { 267 remove(node, ret); 268 } 269 270 return ret; 271 } 272 273 BTreeNode<T>* find(const T& value) const 274 { 275 return find(root(), value); 276 } 277 278 BTreeNode<T>* find(TreeNode<T>* node) const 279 { 280 return find(root(), dynamic_cast<BTreeNode<T>*>(node)); 281 } 282 283 BTreeNode<T>* root() const 284 { 285 return dynamic_cast<BTreeNode<T>*>(this->m_root); 286 } 287 288 int degree() const 289 { 290 return 0; 291 } 292 293 int count() const 294 { 295 return 0; 296 } 297 298 int height() const 299 { 300 return 0; 301 } 302 303 void clear() 304 { 305 free(root()); 306 307 this->m_root = NULL; 308 } 309 310 ~BTree() 311 { 312 clear(); 313 } 314 }; 315 316 } 317 318 #endif // BTREE_H
小结:
以上是关于第六十四课 二叉树中结点的删除与清除的主要内容,如果未能解决你的问题,请参考以下文章