二叉搜索树的实现

这次贴上二叉搜索树的实现,搜索插入删除我都实现了递归和非递归两种版本(递归函数后面有_R标识)

  1 #pragma once
  2 #include<iostream>
  3 using namespace std;
  4 
  5 
  6 template<class K,class V>
  7 struct BSTNode
  8 {
  9     K _key;
 10     V _value;
 11     BSTNode *_left;
 12     BSTNode *_right;
 13     BSTNode(const K& key, const V& value)
 14         :_key(key)
 15         ,_value(value)
 16         ,_left(NULL)
 17         ,_right(NULL)
 18     {
 19     }
 20 };
 21 
 22 
 23 
 24 
 25 
 26 
 27 template<class K,class V>
 28 class BSTree
 29 {
 30     typedef BSTNode<K, V> Node;
 31 public:
 32     BSTree()
 33         :_root(NULL)
 34     {
 35 
 36     }
 37     ~BSTree()
 38     {}
 39     bool Insert(const K& key,const V& value)
 40     {
 41         if (_root == NULL)
 42         {
 43             _root = new Node(key, value);
 44         }
 45         Node *cur = _root;
 46         Node *parent = _root;
 47         while (cur)
 48         {
 49             parent = cur;
 50             if (cur->_key > key)
 51             {
 52                 cur = cur->_left;
 53             }
 54             else if (cur->_key < key)
 55             {
 56                 cur = cur->_right;
 57             }
 58             else
 59             {
 60                 return false;
 61             }
 62         }
 63         if (parent->_key > key)
 64         {
 65             parent->_left = new Node(key, value);
 66         }
 67         else
 68         {
 69             parent->_right = new Node(key, value);
 70         }
 71         return true;
 72     }
 73     bool Insert_R(const K& key, const V& value)
 74     {
 75         return _Insert_R(_root,key,value);
 76     }
 77     bool Remove(const K& key)
 78     {
 79         if (_root == NULL)
 80         {
 81             return false;
 82         }
 83         if (_root->_left == NULL && _root->_right == NULL)
 84         {
 85             delete _root;
 86             _root = NULL;
 87             return true;
 88         }
 89         Node *del = _root;
 90         Node *parent = _root;
 91         while (del && del->_key != key)
 92         {
 93             parent = del;
 94             if (del->_key > key)
 95             {
 96                 del = del->_left;
 97             }
 98             else if (del->_key < key)
 99             {
100                 del = del->_right;
101             }
102         }
103         if (del)
104         {
105             if (del->_left == NULL || del->_right == NULL)
106             {
107                 if (del->_left == NULL)
108                 {
109                     if (parent->_left == del)
110                     {
111                         parent->_left = del->_right;
112                     }
113                     else
114                     {
115                         parent->_right = del->_right;
116                     }
117                 }
118                 else
119                 {
120 
121                     if (parent->_left == del)
122                     {
123                         parent->_left = del->_left;
124                     }
125                     else
126                     {
127                         parent->_right = del->_left;
128                     }
129                 }
130                 delete del;
131                 return true;
132             }
133             else
134             {
135                 Node *InOrderfirst = del->_right;
136                 Node *parent = del;
137                 while (InOrderfirst->_left != NULL)
138                 {
139                     parent = InOrderfirst;
140                     InOrderfirst = InOrderfirst->_left;
141                 }
142                 swap(del->_key, InOrderfirst->_key);
143                 swap(del->_value, InOrderfirst->_value);
144                 if (InOrderfirst->_left == NULL)
145                 {
146                     if (parent->_left == InOrderfirst)
147                     {
148                         parent->_left = InOrderfirst->_right;
149                     }
150                     else
151                     {
152                         parent->_right = InOrderfirst->_right;
153                     }
154                 }
155                 else
156                 {
157 
158                     if (parent->_left == InOrderfirst)
159                     {
160                         parent->_left = InOrderfirst->_left;
161                     }
162                     else
163                     {
164                         parent->_right = InOrderfirst->_left;
165                     }
166                     
167                 }
168                 delete InOrderfirst;
169                 return true;
170             }
171         }
172         return false;
173     }
174     bool Remove_R(const K& key)
175     {
176         return _Remove_R(_root, key);
177     }
178     Node *Find(const K& key)
179     {
180         Node *cur = _root;
181         while (cur)
182         {
183             if (cur->_key > key)
184             {
185                 cur = cur->_left;
186             }
187             else if (cur->_key < key)
188             {
189                 cur = cur->_right;
190             }
191             else
192             {
193                 return cur;
194             }
195         }
196         return NULL;
197     }
198     Node *Find_R(const K& key)
199     {
200         return _Find_R(_root,key);
201     }
202     void InOrder()
203     {
204         return _InOrder(_root);
205     }
206 protected:
207     bool _Remove_R(Node *&root,const K& key)
208     {
209         if (root == NULL)
210         {
211             return false;
212         }
213         if (root->_key > key)
214         {
215             return _Remove_R(root->_left, key);
216         }
217         else if (root->_key < key)
218         {
219             return _Remove_R(root->_right, key);
220         }
221         else
222         {
223             if (root->_left == NULL || root->_right == NULL)
224             {
225                 if (root->_left == NULL)
226                 {
227                     Node *del = root;
228                     root = root->_right;
229                     delete del;
230                     return true;
231                 }
232                 else
233                 {
234                     Node *del = root;
235                     root = root->_left;
236                     delete del;
237                     return true;
238                 }
239             }
240             else
241             {
242                 Node *InOrderfirst = root->_right;
243                 while (InOrderfirst->_left != NULL)
244                 {
245                     InOrderfirst = InOrderfirst->_left;
246                 }
247                 swap(InOrderfirst->_key, root->_key);
248                 swap(InOrderfirst->_value, root->_value);
249                 return _Remove_R(root->_right, key);
250             }
251         }
252     }
253     void _InOrder(Node *root)
254     {
255         if (root == NULL)
256         {
257             return;
258         }
259         _InOrder(root->_left);
260         cout << root->_key << " ";
261         _InOrder(root->_right);
262     }
263     Node *_Find_R(Node *root, const K& key)
264     {
265         if (root == NULL)
266         {
267             return NULL;
268         }
269         if (root->_key < key)
270         {
271             return _Find_R(root->_right, key);
272         }
273         else if (root->_key > key)
274         {
275             return _Find_R(root->_left, key);
276         }
277         else
278         {
279             return root;
280         }
281     }
282     bool _Insert_R(Node *&root, const K& key, const V& value)
283     {
284         if (root == NULL)
285         {
286             root = new Node(key, value);
287             return true;
288         }
289         
290         if (root->_key > key)
291         {
292             return _Insert_R(root->_left, key, value);
293         }
294         else if (root->_key < key)
295         {
296             return _Insert_R(root->_right, key, value);
297         }
298         else
299         {
300             return false;
301         }
302     }
303 protected:
304     Node *_root;
305 };
306 
307 
308 void TestBinarySearchTree()
309 {
310     BSTree<int, int> bst1;
311     int a[10] = { 5,4,3,1,7,8,2,6,0,9 };
312     for (int i = 0; i < 10; ++i)
313     {
314         bst1.Insert(a[i],a[i]);
315     }
316 //    bst1.InOrder();
317     //cout << endl;
318     //cout << bst1.Find(1)->_key << "  ";
319     //cout << bst1.Find(5)->_key << "  ";
320     //cout << bst1.Find(9)->_key << "  ";
321     //cout << bst1.Find_R(1)->_key << "  ";
322     //cout << bst1.Find_R(5)->_key << "  ";
323     //cout << bst1.Find_R(9)->_key << "  ";
324     //cout << endl;
325     bst1.Remove_R(5);
326     bst1.Remove_R(2);
327     bst1.Remove_R(8);
328     for (int i = 0; i < 10; ++i)
329     {
330         bst1.Remove_R(a[i]);
331     }
332     bst1.InOrder();
333     bst1.Remove(5);
334     bst1.Remove(2);
335     bst1.Remove(8);
336     for (int i = 0; i < 10; ++i)
337     {
338         bst1.Remove(a[i]);
339     }
340     bst1.InOrder();
341 }
二叉搜索树的性质:
  1. 每个节点都有一个作为搜索依据的关键码(key),所有节点的关键码互不相同。
  2. 左子树上所有节点的关键码(key)都小于根节点的关键码(key)。
  3. 右子树上所有节点的关键码(key)都大于根节点的关键码(key)。
  4. 左右子树都是二叉搜索树。

插入步骤很简单,就是从根节点开始,进行比较,然后我那个左(右)子树走,走到叶子节点之后,链接上就可以了

寻找也是类似插入的,很简单

删除就要略微繁琐一点有三种情况(其实直接就可以归类为两种)

  • 被删除的节点是叶子节点(左右孩子都是空)
    • 直接删除就可以了
  • 被删除的节点只有一个孩子(左孩子或者右孩子是空)
    • 删除之前需要将父亲节点指针指向被删除节点的孩子
  • 被删除的节点左右孩子都健在(左右孩子都不为空)
    • 删除之前需要和一个特定位置的节点交换
原文地址:https://www.cnblogs.com/lenomirei/p/5394781.html