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

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

 

 

小结:

技术分享图片

 

 

 技术分享图片

 

以上是关于第六十四课 二叉树中结点的删除与清除的主要内容,如果未能解决你的问题,请参考以下文章

数据结构开发(23):二叉树中结点的查找插入删除与清除操作

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

十、二叉树(Binary Tree)

剑指offer二十四之二叉树中和为某一值的路径

leetcode 简单 第六十八题 二叉搜索树的最近公共祖先

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