查找(二叉排序树)

【1】二叉排序树

二叉排序树,又称为二叉查找树。

它或者是一棵空树,或者具有下列性质:

1. 若它的左子树不空,则左子树上所有的结点的值均小于它的根结点的值;

2. 若它的右子树不空,则右子树上所有的结点的值均大于它的根结点的值;

3. 它的左右子树也分别为二叉排序树。

【2】二叉排序树的代码实现

结合下图以及实现代码分析

(1)构建二叉排序树

(2)实现代码

  1 #include <iostream>
  2 using namespace std;
  3 
  4 template<class Type>   class BST;
  5 
  6 template<class Type>
  7 class BstNode
  8 {
  9     friend  class BST<Type>;
 10     Type  data;
 11     BstNode<Type> *leftChild, *rightChild;
 12     public:
 13         BstNode():leftChild(NULL), rightChild(NULL)
 14         {}
 15         BstNode(const Type &x,BstNode<Type> *left = NULL, BstNode<Type> *right = NULL)
 16             : data(x)
 17             , leftChild(left)
 18             , rightChild(right)
 19         {}
 20         ~BstNode()
 21         {}
 22         Type & GetData() { return data;}
 23         const Type & GetData() const { return data;}
 24         BstNode<Type> *&GetLeft() { return leftChild;}
 25         BstNode<Type> * const&GetLeft() const { return leftChild;}
 26         BstNode<Type> * &GetRight() { return rightChild;}
 27         BstNode<Type> * const &GetRight() const { return rightChild;}
 28 };
 29 template<class Type>  
 30 class BST
 31 {
 32 private:
 33     BstNode<Type>  *root;
 34 private:
 35     ///////////////////////////////////私有方法部分
 36     bool insert(BstNode<Type> *&ptr, const Type &x);
 37     bool insertElem(BstNode<Type> *&ptr, const Type &x);
 38     BstNode<Type>* find(BstNode<Type> * ptr, const Type &x);
 39     BstNode<Type>* findRecursive(BstNode<Type> * ptr, const Type &x);
 40     BstNode<Type>* findPre(BstNode<Type> *ptr, const Type &x);
 41     BstNode<Type>* max(BstNode<Type> *ptr) const;
 42     BstNode<Type>* min(BstNode<Type> *ptr) const;
 43     bool remove(BstNode<Type> *&ptr, const Type &x);
 44     bool removeRecursive(BstNode<Type> *&ptr, const Type &x);
 45     void InOrder(BstNode<Type> *ptr) const;
 46     void LevelOrder(BstNode<Type> *t) const;
 47 public:
 48     BST(): root(NULL)
 49     { }
 50     BST(Type x): root(NULL)
 51     { }
 52     ~BST()
 53     { }    
 54     BstNode<Type>* GetRoot()
 55     {
 56         return root;
 57     }
 58     void SetRoot(BstNode<Type>* pRoot)
 59     {
 60         root = pRoot;
 61     }
 62     int Insert(const Type &x)
 63     {
 64         return insert(root, x);
 65     }
 66     BstNode<Type>* Find(const Type &x)
 67     {
 68         return find(root, x);
 69     }
 70     void InOrder()
 71     {
 72         InOrder(root);
 73         cout << endl;
 74     }
 75     BstNode<Type>* Min() const  
 76     {
 77         return min(root);
 78     }
 79     BstNode<Type> * Max() const
 80     {
 81         return max(root);
 82     }
 83     int Remove(const Type &x)
 84     {
 85         return remove(root, x);
 86     }
 87     void LevelOrder()
 88     {
 89         LevelOrder(root);
 90     }
 91 };
 92 // 插入数据元素方法1 (递归实现)
 93 template<class Type>
 94 bool  BST<Type>::insert(BstNode<Type> *&ptr, const Type &x)
 95 {
 96     if (NULL == ptr)
 97     {    // 为空时就需要创建新节点
 98         ptr = new BstNode<Type>(x);
 99         if (NULL == ptr)
100         {
101             cerr << "out of space" << endl;
102             return false;
103         }
104         return true;
105     }
106     else if (x < ptr->data)   
107     {    // 小, 插入其左边
108         return insert(ptr->leftChild, x);
109     }
110     else if (x > ptr->data)
111     {    // 大, 插入其右边
112         return insert(ptr->rightChild, x);
113     }
114     else
115     {    // 两者相等
116         cout << "数据" << x << "重复,请重新输入..." << endl;
117         return false;
118     }
119 }
120 // 插入数据元素方法2 (非递归实现)
121 template<class Type>
122 bool BST<Type>::insertElem(BstNode<Type> *&ptr, const Type &x)
123 {
124     if (NULL == ptr)
125     {
126         ptr = new BstNode<Type>(x);
127         if (NULL == ptr)
128         {
129             cout << "out of space !" << endl;
130             return false;
131         }
132         return true;
133     }
134     BstNode<Type>* p = ptr, *q = NULL;
135     while (p != NULL)
136     {
137         q = p;
138         if (x == p->data)
139         {
140             cout << "数据重复" << endl;
141             return false;
142         }
143         if (x > p->data)
144         {
145             p = p->rightChild;
146         }
147         else if (x < p->data)
148         {
149             p = p->leftChild;
150         }
151     }
152     p = new BstNode<Type>(x);
153     if (x < q->data)
154         q->leftChild = p;
155     if (x > q->data)
156         q->rightChild = p;
157     return true;
158 }
159 // 查找某个数据元素的节点指针 (递归实现)
160 template<class Type>
161 BstNode<Type>* BST<Type>::findRecursive(BstNode<Type> *ptr, const Type &x)
162 {
163     if (NULL == ptr)
164         return NULL;
165     else if (x < ptr->data)
166         return find(ptr->leftChild, x);
167     else if (x > ptr->data)
168         return find(ptr->rightChild, x);
169     else
170         return ptr;
171 }
172 // 查找某个数据元素的节点指针 (非递归实现)
173 template<class Type>
174 BstNode<Type>* BST<Type>::find(BstNode<Type> *ptr, const Type &x)
175 {
176     while (ptr != NULL)
177     {
178         if (x == ptr->data)  
179             return ptr;
180         else if (ptr->data > x)
181             ptr = ptr->leftChild;
182         else
183             ptr = ptr->rightChild;
184     }
185     return  NULL;
186 }
187 // 查找某个数据元素的父节点指针 (非递归实现)
188 // 记录父节点,当孩子值与查找的数据元素值相同,返回父节点即可。
189 template<class Type>
190 BstNode<Type>* BST<Type>::findPre(BstNode<Type> *ptr, const Type &x)
191 {
192     BstNode<Type>* q = NULL;
193     while (ptr != NULL)
194     {
195         if (x == ptr->data)  
196         {
197             return q;
198         }
199         else if (ptr->data > x)
200         {
201             q = ptr;
202             ptr = ptr->leftChild;
203         }
204         else
205         {
206             q = ptr;
207             ptr = ptr->rightChild;
208         }
209     }
210     return  NULL;
211 }
212 // 按元素值删除某个节点 (递归实现)
213 // 具体删除思路请参考注释
214 template<class Type>    
215 bool BST<Type>::removeRecursive(BstNode<Type> *&ptr, const Type &x)
216 {
217     BstNode<Type>* tmp = NULL;
218     if (ptr != NULL)
219     { 
220         if (x < ptr->data)      // 小于,转向左子树
221             return remove(ptr->leftChild, x);
222         else if (x > ptr->data) // 大于,转向右子树
223             return remove(ptr->rightChild, x);
224         // 相等时即找到  然后判断左右子树情况
225         else if (ptr->leftChild != NULL && ptr->rightChild != NULL)  
226         {    
227             // 1. 左右均不空
228             tmp = min(ptr->rightChild); // 找到右子树的最小值结点
229             ptr->data = tmp->data;        // 数值更换
230             return remove(ptr->rightChild, ptr->data); // 递归再删除那个最小值结点
231         }
232         else 
233         {    // 2. 左为空 || 右为空 || 左右子树均为空
234             tmp = ptr;
235             if (NULL == ptr->leftChild)     // 先考虑左子树
236                 ptr = ptr->rightChild;   // 衔接其右节点
237             else if (NULL == ptr->rightChild) // 再考虑右子树
238                 ptr = ptr->leftChild;          // 衔接其左节点
239 
240             delete tmp;
241             tmp = NULL;  
242             return true;
243         }
244     }
245     return false;
246 }
247 // 按元素值删除某个节点 (非递归实现)
248 // 具体删除思路请参考注释
249 template<class Type>    
250 bool BST<Type>::remove(BstNode<Type> *&ptr, const Type &x)
251 {
252     BstNode<Type>* pself = find(ptr, x); // 欲删除结点自身
253     BstNode<Type>* parent = findPre(ptr, x); // 欲删除结点的父节点
254     BstNode<Type>* pDelete = pself; // 最终删除结点
255     if (NULL == pself)
256     {
257         cout << "删除数据不存在!" << endl;
258         return false;
259     }
260     // 满足以下情况时需要转换一下实际删除节点
261     if (pself->leftChild != NULL && pself->rightChild != NULL)  
262     {    
263         pDelete = min(pself->rightChild);    // 找到右子树的最小值结点,将来删除它即可
264         pself->data = pDelete->data;         // 数值更换
265         parent = findPre(pself->rightChild, pself->data); // 重新确定实际删除对象的父节点
266         if (NULL == parent)
267         {
268             // 当删除右子树的根节点 (只有可能右子树存在)
269             ptr->rightChild = pDelete->rightChild; // 衔接右子树即可
270             // 执行删除 释放内存
271             delete pDelete;
272             pDelete = NULL;
273             return true;
274         }
275     }
276     // 当欲删除父节点  且其孩子为空
277     if (NULL == parent)
278     {
279         if (NULL == pself->leftChild && 
280             NULL == pself->rightChild)
281         {    // 当树只有一个根节点 两孩子都为空
282             delete ptr;
283             ptr = NULL;
284             return true;
285         }
286         else if (NULL == pself->leftChild)
287         {    // 右孩子存在
288             ptr = pself->rightChild;
289         }
290         else if (NULL == pself->rightChild)
291         {    // 左孩子存在
292             ptr = pself->leftChild;
293         }
294     }
295     else
296     {
297         // 衔接结点
298         if (parent->data < pDelete->data)
299         {    // 右孩子
300             if (NULL == pDelete->leftChild)    
301                 parent->rightChild = pDelete->rightChild;
302             else if (NULL == pDelete->rightChild) 
303                 parent->rightChild = pDelete->leftChild;         
304         }
305         else
306         {    // 左孩子
307             if (NULL == pDelete->leftChild)    
308                 parent->leftChild = pDelete->rightChild; 
309             else if (NULL == pDelete->rightChild) 
310                 parent->leftChild = pDelete->leftChild;
311         }
312     }
313     // 执行删除 释放内存
314     delete pDelete;
315     pDelete = NULL;
316     return true;
317 }
318 // 打印二叉搜索树的数据 (中序遍历)
319 // 思路分析:
320 // 先遍历左子树
321 // 再遍历根节点
322 // 最后遍历右子树
323 template<class Type>
324 void BST<Type>::InOrder(BstNode<Type> *ptr) const
325 {
326     if (ptr != NULL)
327     {
328         InOrder(ptr->leftChild);
329         cout << ptr->data << " ";
330         InOrder(ptr->rightChild);
331     }
332 }
333 // 求二叉搜索树某一个子树的最小元素指针
334 // 思路分析:
335 // 一直向左子树递进即为最小
336 template<class Type>
337 BstNode<Type>* BST<Type>::min(BstNode<Type> *ptr) const
338 {
339     BstNode<Type> *p = ptr;
340     while (p != NULL && p->leftChild != NULL)
341     {
342         p = p->leftChild;
343     }
344     return p;
345 }
346 // 求二叉搜索树某一个子树的最大元素指针
347 // 思路分析:
348 // 一直向右子树递进即为最大
349 template<class Type>
350 BstNode<Type>* BST<Type>::max(BstNode<Type> *ptr) const
351 {
352     BstNode<Type> *p = ptr;
353     while (p != NULL && p->rightChild != NULL)  // 保证p不等于空!
354     {
355         p = p->rightChild;
356     }
357     return p;
358 }
359 
360 void main()
361 {
362     BST<int> bst;
363     int a[12] = {53,17,9,45,23,40,38,78,65,87,81,94};
364     for (int i = 0; i < 12; ++i)
365     {
366         bst.Insert(a[i]);
367     }
368     cout << "中序遍历的结果如下:" << endl;
369     bst.InOrder();
370 
371     int data = 0;
372     cout << "请输入要查找的数据:";
373     cin >> data;
374     if (bst.Find(data) != NULL)
375         cout << "查找成功!" << endl;
376     else
377         cout << "未查找到!" << endl;
378 
379     cout << "请输入要删除的数据:";
380     for (; ;)
381     {
382         int num = 0;
383         while (cin >> num, num != -1)
384         {
385             if (-1 == num)  
386                 break;
387             bst.Remove(num);
388             cout << "删除后数据打印:" << endl;
389             bst.InOrder();
390             cout << "请输入要删除的数据(-1结束):";
391         }
392         break;
393     }
394 }

Good  Good  Study, Day  Day  Up.

顺序  选择  循环  总结

原文地址:https://www.cnblogs.com/Braveliu/p/3467097.html