二叉树之二叉搜索树(BSTree)

Posted dua677

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二叉树之二叉搜索树(BSTree)相关的知识,希望对你有一定的参考价值。

二叉搜索树(Binary Search Tree)

  二叉搜索树是一种二叉树,子结点数量上限为2;为了方便搜索,结点是有序的,左结点的key不大于父节点,右节点的key不小于父节点,且左右子树也是二叉搜索树。

  下面是一个二叉搜索树的样图,来自维基

  技术图片

技术图片

  一棵树一般都要提供一些函数,例如遍历、搜索、最大最小值、插入,删除,销毁等

  代码含注释,下面是输出效果(msys2)

技术图片

代码

开发环境:Qt Creator 4.8.2  Mingw64 7.3  windows 8.1

完整代码:https://github.com/Duacai/Data-Structure-and-Algorithms/tree/master/BSTree

Object.h

技术图片
 1 #ifndef OBJECT_H
 2 #define OBJECT_H
 3 
 4 #include <iomanip>    // size_t
 5 
 6 namespace LinWeiJie_lib
 7 {
 8 
 9 class Object
10 {
11 public:
12     void* operator new(size_t size);
13     void operator delete(void* p);
14     void* operator new[](size_t size);
15     void operator delete[](void* p);
16     bool operator == (const Object& obj);
17     bool operator != (const Object& obj);
18     virtual ~Object() = 0;
19 };
20 
21 }
22 
23 #endif // OBJECT_H
View Code

Exception.h

技术图片
  1 #ifndef EXCEPTION_H
  2 #define EXCEPTION_H
  3 
  4 #include "Object.h"
  5 
  6 namespace LinWeiJie_lib
  7 {
  8 
  9 #define THROW_EXCEPTION(e, m) (throw e(m, __FILE__, __LINE__))  // 注释掉throw语句即可兼容老版本的不支持异常处理的C++编译器
 10 
 11 class Exception : public Object
 12 {
 13 protected:
 14     char* m_message;
 15     char* m_location;
 16 
 17     void init(const char* message, const char* file, int line);
 18 public:
 19     Exception(const char* message);
 20     Exception(const char* file, int line);
 21     Exception(const char* message, const char* file, int line);
 22 
 23     Exception(const Exception& e);
 24     Exception& operator= (const Exception& e);
 25 
 26     virtual const char* message() const;
 27     virtual const char* location() const;
 28 
 29     virtual ~Exception() = 0;
 30 };
 31 
 32 class ArithmeticException : public Exception    // 算术异常
 33 {
 34 public:
 35     ArithmeticException() : Exception(nullptr){}
 36     ArithmeticException(const char* message) : Exception(message){}
 37     ArithmeticException(const char* file, int line) : Exception(file, line){}
 38     ArithmeticException(const char* message, const char* file, int line) : Exception(message, file, line){}
 39 
 40     ArithmeticException(const ArithmeticException& e) : Exception(e){}
 41 
 42     ArithmeticException& operator=(const ArithmeticException& e)
 43     {
 44         Exception::operator=(e);
 45 
 46         return *this;
 47     }
 48 
 49     ~ArithmeticException();
 50 };
 51 
 52 class NullPointerException : public Exception  // 空指针异常
 53 {
 54 public:
 55     NullPointerException() : Exception(nullptr) {}
 56     NullPointerException(const char* message) : Exception(message) {}
 57     NullPointerException(const char* file, int line) : Exception(file, line) {}
 58     NullPointerException(const char* message, const char* file, int line) : Exception(message, file, line) {}
 59 
 60     NullPointerException(const NullPointerException& e) : Exception(e) {}
 61 
 62     NullPointerException& operator= (const NullPointerException& e)
 63     {
 64         Exception::operator=(e);
 65 
 66         return *this;
 67     }
 68 
 69     ~NullPointerException();
 70 };
 71 
 72 class IndexOutOfBoundsException : public Exception    // 下标越界异常
 73 {
 74 public:
 75     IndexOutOfBoundsException() : Exception(nullptr) {}
 76     IndexOutOfBoundsException(const char* message) : Exception(message) {}
 77     IndexOutOfBoundsException(const char* file, int line) : Exception(file, line) {}
 78     IndexOutOfBoundsException(const char* message, const char* file, int line) : Exception(message, file, line) {}
 79 
 80     IndexOutOfBoundsException(const IndexOutOfBoundsException& e) : Exception(e) {}
 81 
 82     IndexOutOfBoundsException& operator= (const IndexOutOfBoundsException& e)
 83     {
 84         Exception::operator=(e);
 85 
 86         return *this;
 87     }
 88 
 89     ~IndexOutOfBoundsException();
 90 };
 91 
 92 class NoEnoughMemoryException : public Exception    // 内存不足异常
 93 {
 94 public:
 95     NoEnoughMemoryException() : Exception(nullptr) {}
 96     NoEnoughMemoryException(const char* message) : Exception(message) {}
 97     NoEnoughMemoryException(const char* file, int line) : Exception(file, line) {}
 98     NoEnoughMemoryException(const char* message, const char* file, int line) : Exception(message, file, line) {}
 99 
100     NoEnoughMemoryException(const NoEnoughMemoryException& e) : Exception(e) {}
101 
102     NoEnoughMemoryException& operator= (const NoEnoughMemoryException& e)
103     {
104         Exception::operator=(e);
105 
106         return *this;
107     }
108 
109     ~NoEnoughMemoryException();
110 };
111 
112 class InvalidParameterException : public Exception  // 无效参数异常
113 {
114 public:
115     InvalidParameterException() : Exception(nullptr) {}
116     InvalidParameterException(const char* message) : Exception(message) {}
117     InvalidParameterException(const char* file, int line) : Exception(file, line) {}
118     InvalidParameterException(const char* message, const char* file, int line) : Exception(message, file, line) {}
119 
120     InvalidParameterException(const InvalidParameterException& e) : Exception(e) {}
121 
122     InvalidParameterException& operator= (const InvalidParameterException& e)
123     {
124         Exception::operator=(e);
125 
126         return *this;
127     }
128 
129     ~InvalidParameterException();
130 };
131 
132 class InvalidOperationException : public Exception  // 无效操作异常
133 {
134 public:
135     InvalidOperationException() : Exception(nullptr) {}
136     InvalidOperationException(const char* message) : Exception(message) {}
137     InvalidOperationException(const char* file, int line) : Exception(file, line) {}
138     InvalidOperationException(const char* message, const char* file, int line) : Exception(message, file, line) {}
139 
140     InvalidOperationException(const InvalidOperationException& e) : Exception(e) {}
141 
142     InvalidOperationException& operator= (const InvalidOperationException& e)
143     {
144         Exception::operator=(e);
145 
146         return *this;
147     }
148 
149     ~InvalidOperationException();
150 };
151 
152 class DuplicateDataException : public Exception    // 重复数据异常
153 {
154 public:
155     DuplicateDataException() : Exception(nullptr) {}
156     DuplicateDataException(const char* message) : Exception(message) {}
157     DuplicateDataException(const char* file, int line) : Exception(file, line) {}
158     DuplicateDataException(const char* message, const char* file, int line) : Exception(message, file, line) {}
159 
160     DuplicateDataException(const DuplicateDataException& e) : Exception(e) {}
161 
162     DuplicateDataException& operator= (const DuplicateDataException& e)
163     {
164         Exception::operator=(e);
165 
166         return *this;
167     }
168 
169     ~DuplicateDataException();
170 };
171 
172 class FileOversizeException : public Exception    // 文件太大异常
173 {
174 public:
175     FileOversizeException() : Exception(nullptr) {}
176     FileOversizeException(const char* message) : Exception(message) {}
177     FileOversizeException(const char* file, int line) : Exception(file, line) {}
178     FileOversizeException(const char* message, const char* file, int line) : Exception(message, file, line) {}
179 
180     FileOversizeException(const FileOversizeException& e) : Exception(e) {}
181 
182     FileOversizeException& operator= (const FileOversizeException& e)
183     {
184         Exception::operator=(e);
185 
186         return *this;
187     }
188 
189     ~FileOversizeException();
190 };
191 
192 class EmptyTreeException : public Exception    // 空树异常
193 {
194 public:
195     EmptyTreeException() : Exception(nullptr) {}
196     EmptyTreeException(const char* message) : Exception(message) {}
197     EmptyTreeException(const char* file, int line) : Exception(file, line) {}
198     EmptyTreeException(const char* message, const char* file, int line) : Exception(message, file, line) {}
199 
200     EmptyTreeException(const EmptyTreeException& e) : Exception(e) {}
201 
202     EmptyTreeException& operator= (const EmptyTreeException& e)
203     {
204         Exception::operator=(e);
205 
206         return *this;
207     }
208 
209     ~EmptyTreeException();
210 };
211 
212 }
213 
214 #endif // EXCEPTION_H
View Code

Tree.h

技术图片
  1 #ifndef TREE_H
  2 #define TREE_H
  3 
  4 #include <iomanip>
  5 
  6 namespace LinWeiJie_lib
  7 {
  8 
  9 template < typename T >
 10 class TNode
 11 {
 12 public:
 13     T mKey;
 14 
 15     TNode() = delete;
 16     TNode(const T& key);
 17     TNode(const TNode<T>& tNode) = default;
 18     TNode(TNode<T> && tNode) = default;
 19     TNode<T>& operator = (const TNode<T>& tNode) = default;
 20     TNode<T>& operator = (TNode<T> && tNode) = default;
 21     virtual ~TNode() = 0;
 22 };
 23 
 24 template < typename T >
 25 TNode<T>::TNode(const T& key) : mKey(key)
 26 {
 27 }
 28 
 29 template < typename T >
 30 TNode<T>::~TNode()
 31 {
 32 }
 33 
 34 template < typename T >
 35 class Tree
 36 {
 37 protected:
 38     TNode<T>*    mRoot;
 39     size_t        mCount;
 40 
 41     Tree();
 42     Tree(const Tree<T>& tree) = delete;
 43     Tree(Tree<T> && tree);
 44     Tree<T>& operator = (const Tree<T>& tree) = delete;
 45     Tree<T>& operator = (Tree<T> && tree);
 46     virtual ~Tree() = 0;
 47 
 48 public:
 49     virtual void preOrder() const = 0;
 50     virtual void inOrder() const = 0;
 51     virtual void postOrder() const = 0;
 52     virtual void levelOrder() const = 0;
 53 
 54     virtual TNode<T>* search(const T& key) const = 0;            // 递归版
 55     virtual TNode<T>* iterativeSearch(const T& key) const = 0;    // 非递归版
 56 
 57     virtual void insert(const T& node) = 0;
 58     virtual void remove(const T& node) = 0;
 59     virtual void destroy() = 0;
 60 
 61     virtual const T& getRootKey() const = 0;
 62     virtual void printTree() const = 0;
 63 };
 64 
 65 template < typename T >
 66 Tree<T>::Tree() : mRoot(nullptr), mCount(0)
 67 {
 68 }
 69 
 70 template < typename T >
 71 Tree<T>::Tree(Tree<T> && tree)
 72 {
 73     mRoot = tree.mRoot;
 74     mCount = tree.mCount;
 75 
 76     tree.mRoot = nullptr;
 77     tree.mCount = 0;
 78 }
 79 
 80 template < typename T >
 81 Tree<T>& Tree<T>::operator = (Tree<T> && tree)
 82 {
 83     if ( this == &tree )
 84         return *this;
 85     
 86     mRoot = tree.mRoot;
 87     mCount = tree.mCount;
 88     
 89     tree.mRoot = nullptr;
 90     tree.mCount = 0;
 91 }
 92 
 93 template < typename T >
 94 Tree<T>::~Tree()
 95 {
 96 }
 97 
 98 }
 99 
100 #endif
View Code

BSTree.h

技术图片
  1 #ifndef BSTREE_H
  2 #define BSTREE_H
  3 
  4 #include <iostream>
  5 #include <stack>
  6 #include <queue>
  7 
  8 #include "Exception.h"
  9 #include "Tree.h"
 10 
 11 using namespace std;
 12 
 13 namespace LinWeiJie_lib
 14 {
 15 
 16 template < typename T >
 17 class BSTNode : public TNode<T>
 18 {
 19 public:
 20     BSTNode<T>    *mLeft;
 21     BSTNode<T>    *mRight;
 22     BSTNode<T>    *mParent;
 23 
 24     BSTNode() = delete;
 25     BSTNode(const T& key, BSTNode<T> *left, BSTNode<T> *right, BSTNode<T> *parent);
 26     BSTNode(const BSTNode<T>& tree) = delete;
 27     BSTNode(BSTNode<T> && tree);
 28     BSTNode<T>& operator = (const BSTNode<T>& tree) = delete;
 29     BSTNode<T>& operator = (BSTNode<T> && tree);
 30     virtual ~BSTNode();
 31 };
 32 
 33 template < typename T >
 34 BSTNode<T>::BSTNode(const T& key, BSTNode<T> *left, BSTNode<T> *right, BSTNode<T> *parent) :
 35     TNode<T> (key), mLeft(left), mRight(right), mParent(parent)
 36 {
 37 }
 38 
 39 template < typename T >
 40 BSTNode<T>::BSTNode(BSTNode<T> && tree)
 41 {
 42     mLeft = tree.mLeft;
 43     mRight = tree.mRight;
 44     mParent = tree.mParent;
 45 
 46     tree->mLeft = nullptr;
 47     tree->mRight = nullptr;
 48     tree->mParent = nullptr;
 49 }
 50 
 51 template < typename T >
 52 BSTNode<T>& BSTNode<T>::operator = (BSTNode<T> && tree)
 53 {
 54     if ( this == &tree )
 55         return *this;
 56     
 57     delete mLeft;
 58     delete mRight;
 59     delete mParent;
 60     
 61     mLeft = tree->mLeft;
 62     mRight = tree->mRight;
 63     mParent = tree->mParent;
 64 
 65     return *this;
 66 }
 67 
 68 template < typename T >
 69 BSTNode<T>::~BSTNode()
 70 {
 71 
 72 }
 73 
 74 template < typename T >
 75 class BSTree : public Tree<T>
 76 {
 77 protected:
 78     virtual void preOrder(BSTNode<T> *tree) const;                                // 深度优先的前、中、后序遍历
 79     virtual void inOrder(BSTNode<T> *tree) const;
 80     virtual void postOrder(BSTNode<T> *tree) const;
 81 
 82     virtual void levelOrder(BSTNode<T> *tree) const;                            // 广度优先
 83 
 84     virtual BSTNode<T>* search(BSTNode<T> *tree, const T& key) const;            // 递归版搜索
 85     virtual BSTNode<T>* iterativeSearch(BSTNode<T> *tree, const T& key) const;    // 非递归版搜索
 86 
 87     virtual BSTNode<T>* minimum(BSTNode<T> *tree) const;                        // 获取最小最大值
 88     virtual BSTNode<T>* maximum(BSTNode<T> *tree) const;
 89 
 90     virtual BSTNode<T>* successor(BSTNode<T> *node) const;                        // 查找后继,即大于又最接近node的节点
 91     virtual BSTNode<T>* predecessor(BSTNode<T> *node) const;                    // 查找前继
 92 
 93     virtual void insert(BSTNode<T> *node);
 94     virtual BSTNode<T>* remove(BSTNode<T> *node);                                // 返回值用于删除,返回值实际是替换结点
 95     virtual void destroy(BSTNode<T> *tree);
 96 
 97     void printTree(BSTNode<T> *tree, bool firstNode) const;                        // 打印树,类似linux的tree命令
 98 
 99     virtual int height(BSTNode<T> *tree) const;                                    // 树的高度
100     virtual int degree(BSTNode<T> *tree) const;                                    // 结点的度数
101 
102 public:
103     BSTree();
104     BSTree(const BSTree<T>&) = default;
105     BSTree(BSTree<T> &&) = default;
106     BSTree<T>& operator = (const BSTree<T>&) = default;
107     BSTree<T>& operator = (BSTree<T> &&) = default;
108     virtual ~BSTree();
109 
110     virtual void preOrder() const;
111     virtual void inOrder() const;
112     virtual void postOrder() const;
113 
114     virtual void levelOrder() const;
115 
116     virtual BSTNode<T>* search(const T& key) const;
117     virtual BSTNode<T>* iterativeSearch(const T& key) const;
118 
119     virtual const T& minimum() const;
120     virtual const T& maximum() const;
121 
122     virtual void insert(const T& key);
123     virtual void remove(const T& key);
124     virtual void destroy();
125 
126     virtual int height() const;
127     virtual int degree() const;
128 
129     virtual size_t getCount() const;
130 
131     virtual const T& getRootKey() const;
132     virtual void printTree() const;
133 };
134 
135 template < typename T >
136 BSTree<T>::BSTree() : Tree<T> ()
137 {
138 }
139 
140 template < typename T >
141 void BSTree<T>::preOrder(BSTNode<T> *tree) const
142 {
143     if ( tree != nullptr )
144     {
145         cout << tree->mKey << " " << flush;
146         preOrder(tree->mLeft);
147         preOrder(tree->mRight);
148     }
149 }
150 
151 template < typename T >
152 void BSTree<T>::preOrder() const
153 {
154     preOrder(dynamic_cast<BSTNode<T>*>(this->mRoot));
155 }
156 
157 template < typename T >
158 void BSTree<T>::inOrder(BSTNode<T> *tree) const
159 {
160     if ( tree != nullptr )
161     {
162         inOrder(tree->mLeft);
163         cout << tree->mKey << " " << flush;
164         inOrder(tree->mRight);
165     }
166 }
167 
168 template < typename T >
169 void BSTree<T>::inOrder() const
170 {
171     inOrder(dynamic_cast<BSTNode<T>*>(this->mRoot));
172 }
173 
174 template < typename T >
175 void BSTree<T>::postOrder(BSTNode<T> *tree) const
176 {
177     if ( tree != nullptr )
178     {
179         postOrder(tree->mLeft);
180         postOrder(tree->mRight);
181         cout << tree->mKey << " " << flush;
182     }
183 }
184 
185 template < typename T >
186 void BSTree<T>::postOrder() const
187 {
188     postOrder(dynamic_cast<BSTNode<T>*>(this->mRoot));
189 }
190 
191 template < typename T >
192 void BSTree<T>::levelOrder(BSTNode<T> *tree) const
193 {
194     if ( tree != nullptr )
195     {
196         queue<BSTNode<T>*> tmp;
197         tmp.push(tree);
198 
199         while( tmp.size() > 0 )
200         {
201             BSTNode<T>* t = tmp.front();
202             tmp.pop();
203 
204             if ( t->mLeft != nullptr )
205                 tmp.push(t->mLeft);
206 
207             if ( t->mRight != nullptr )
208                 tmp.push(t->mRight);
209 
210             cout << t->mKey << " " << flush;
211         }
212     }
213 }
214 
215 template < typename T >
216 void BSTree<T>::levelOrder() const
217 {
218     levelOrder(dynamic_cast<BSTNode<T>*>(this->mRoot));
219 }
220 
221 template < typename T >
222 BSTNode<T>* BSTree<T>::search(BSTNode<T> *node, const T& key) const
223 {
224     if ( node == nullptr || node->mKey == key )
225     {
226         return node;
227     }
228     else if ( key < node->mKey )
229         return search(dynamic_cast<BSTNode<T>*>(node)->mLeft, key);
230     else
231         return search(dynamic_cast<BSTNode<T>*>(node)->mRight, key);
232 }
233 
234 template < typename T >
235 BSTNode<T>* BSTree<T>::search(const T& key) const
236 {
237     return search(dynamic_cast<BSTNode<T>*>(this->mRoot), key);
238 }
239 
240 template < typename T >
241 BSTNode<T>* BSTree<T>::iterativeSearch(BSTNode<T>* node, const T& key) const
242 {
243     while ( (node != nullptr) && (node->mKey != key) )
244     {
245         if ( key < node->mKey )
246             node = node->mLeft;
247         else
248             node = node->mRight;
249     }
250 
251     return node;
252 }
253 
254 template < typename T >
255 BSTNode<T>* BSTree<T>::iterativeSearch(const T& value) const
256 {
257     return iterativeSearch(dynamic_cast<BSTNode<T>*>(this->mRoot), value);
258 }
259 
260 template < typename T >
261 BSTNode<T>* BSTree<T>::minimum(BSTNode<T>* tree) const
262 {
263     if ( tree == nullptr )
264         return nullptr;
265 
266     while ( tree->mLeft != nullptr )
267         tree = tree->mLeft;
268 
269     return tree;
270 }
271 
272 template < typename T >
273 const T& BSTree<T>::minimum() const
274 {
275     BSTNode<T> *p = minimum(dynamic_cast<BSTNode<T>*>(this->mRoot));
276     if ( p == nullptr )
277         THROW_EXCEPTION(EmptyTreeException, "The tree is empty ...");
278 
279     return p->mKey;
280 }
281 
282 template < typename T >
283 BSTNode<T>* BSTree<T>::maximum(BSTNode<T>* tree) const
284 {
285     if ( tree == nullptr )
286         return nullptr;
287 
288     while ( tree->mRight != nullptr )
289         tree = tree->mRight;
290 
291     return tree;
292 }
293 
294 template < typename T >
295 const T& BSTree<T>::maximum() const
296 {
297     BSTNode<T> *p = maximum(dynamic_cast<BSTNode<T>*>(this->mRoot));
298     if ( p == nullptr )
299         THROW_EXCEPTION(EmptyTreeException, "The tree is empty ...");
300 
301     return p->mKey;
302 }
303 
304 template < typename T >
305 BSTNode<T>* BSTree<T>::successor(BSTNode<T> *node) const    // 查找后继
306 {
307     if ( node->mRight != nullptr )                            // 如果node有右孩子,则在它的右孩子里面最小的是后继
308     {
309         return minimum(node->mRight);
310     }
311 
312     BSTNode<T>* ret = node->mParent;                        // 如果node没有右孩子,且它自身是左孩子,则它的父亲是后继
313     while ( (ret != nullptr) && (node == ret->mRight) )        // 如果node没有右孩子,且它自身是右孩子,它的最近祖先是左孩子的,则这个祖先的父亲就是后继
314     {
315         node = ret;
316         ret = ret->mParent;
317     }
318 
319     return ret;
320 }
321 
322 template < typename T >
323 BSTNode<T>* BSTree<T>::predecessor(BSTNode<T>* node) const    // 查找前继
324 {
325     if ( node->mLeft != nullptr )                            // 如果node有左孩子,则在它的左孩子里面最大的是前继
326         return maximum(node->mLeft);
327 
328     BSTNode<T>* ret = node->mParent;                        // 如果node没有左孩子,且它自身是右孩子,则它的父亲是后继
329     while ( (ret != nullptr) && (node == ret->mLeft) )        // 如果node没有左孩子,且它自身是左孩子,它的最近祖先是右孩子的,则这个祖先的父亲就是后继
330     {
331         node = ret;
332         ret = ret->mLeft;
333     }
334 
335     return ret;
336 }
337 
338 template < typename T >
339 void BSTree<T>::insert(BSTNode<T>* node)
340 {
341     BSTNode<T>* in = nullptr;                // 插入点
342     BSTNode<T>* parent = dynamic_cast<BSTNode<T>*>(this->mRoot);        // 插入点的父节点
343 
344     while ( parent != nullptr )                // 查找node的插入点
345     {
346         in = parent;
347         if ( node->mKey < in->mKey )        // 如果node结点小于插入点,则插入到左孩子分支
348             parent = parent->mLeft;
349         else if ( node->mKey > in->mKey )    // 如果node结点大于插入点,则插入到右孩子分支
350             parent = parent->mRight;
351         else                                // 如果数据等同则跳出
352             break;
353     }
354 
355     node->mParent = in;                    // 设置node结点的父亲为插入点
356     if ( in == nullptr )                // 如果插入点为空,设node结点为根节点
357         this->mRoot = node;
358     else if ( node->mKey < in->mKey )    // 如果node结点小于插入点,插入左边
359         in->mLeft = node;
360     else if ( node->mKey > in->mKey )    // 如果node结点大于插入点,插入右边
361         in->mRight = node;
362     else                                // 如果数据等同则直接替换并释放插入的结点
363     {
364         in->mKey = node->mKey;
365         delete node;
366         return;
367     }
368 
369     ++this->mCount;                        // 结点统计,注意重复结点插入时不能增加
370 }
371 
372 template < typename T >
373 void BSTree<T>::insert(const T& key)
374 {
375     insert(new BSTNode<T>(key, nullptr, nullptr, nullptr));
376 }
377 
378 template < typename T >
379 BSTNode<T>* BSTree<T>::remove(BSTNode<T> *node)
380 {
381     BSTNode<T>* replace = nullptr;            // 代替结点
382     BSTNode<T>* del = nullptr;                // 删除点
383 
384     if ( (node->mLeft == nullptr) || (node->mRight == nullptr) )    // 如果孩子不全,node就是删除点,可以直接用仅有的孩子代替
385         del = node;
386     else                                                            // 否则有两个孩子,后继就是删除点(右子树中最小的成员)
387     {
388         del = successor(node);                                        // 查找后继
389         node->mKey = del->mKey;                                        // 直接用后继key替换node的key
390     }
391 
392     if ( del->mLeft != nullptr )            // 如果有左孩子,则更新左孩子为代替结点(如果if成立就只有左孩子)
393         replace = del->mLeft;
394     else                                    // 否则设右孩子为代替结点
395         replace = del->mRight;
396 
397     if ( replace != nullptr )                // 如果代替结点不是空树,更新代替结点的父亲
398         replace->mParent = del->mParent;
399 
400     if ( del->mParent == nullptr )            // 如果结点是根节点且孩子不全,那就直接替换
401         this->mRoot = replace;
402     else if ( del == del->mParent->mLeft )    // 如果删除点为左孩子,则更新父节点的左孩子
403         del->mParent->mLeft = replace;
404     else                                    // 否则更新父节点的右孩子
405         del->mParent->mRight = replace;
406 
407     --this->mCount;
408 
409     return del;
410 }
411 
412 template < typename T >
413 void BSTree<T>::remove(const T& key)
414 {
415     BSTNode<T> *del = nullptr, *node;
416     del = search(dynamic_cast<BSTNode<T>*>(this->mRoot), key);
417 
418     if ( del != nullptr )                        // 找到的删除点不为空
419         if ( (node = remove(del)) != nullptr )    // 删除node并返回代替结点
420             delete node;                        // 删除代替结点
421 }
422 
423 template < typename T >
424 void BSTree<T>::destroy(BSTNode<T> *tree)
425 {
426     if ( tree == nullptr )
427         return;
428 
429     if ( tree->mLeft != nullptr )
430         destroy(tree->mLeft);
431 
432     if ( tree->mRight != nullptr )
433         destroy(tree->mRight);
434 
435     delete tree;
436     tree = nullptr;
437 }
438 
439 template < typename T >
440 void BSTree<T>::destroy()
441 {
442     destroy(dynamic_cast<BSTNode<T>*>(this->mRoot));
443     this->mRoot = nullptr;
444     this->mCount = 0;
445 }
446 
447 template < typename T >
448 int BSTree<T>::height(BSTNode<T>* node) const
449 {
450     int ret = 0;
451 
452     if( node != nullptr )
453     {
454         int lh = height(node->mLeft);
455         int rh = height(node->mRight);
456 
457         ret = ((lh > rh) ? lh : rh) + 1;
458     }
459 
460     return ret;
461 }
462 
463 template < typename T >
464 int BSTree<T>::height() const
465 {
466     int ret = 0;
467 
468     if( this->mRoot != nullptr )
469     {
470         ret = height(dynamic_cast<BSTNode<T>*>(this->mRoot));
471     }
472 
473     return ret;
474 }
475 
476 template < typename T >
477 int BSTree<T>::degree(BSTNode<T>* node) const
478 {
479     int ret = 0;
480 
481     if( node != nullptr )
482     {
483         BSTNode<T>* child[] = { node->mLeft, node->mRight };
484 
485         ret = (!!node->mLeft + !!node->mRight);        // 统计有效结点数,!!用于转换成bool类型,如果是有效结点则为1,否则为0
486 
487         for(int i=0; (i<2) && (ret<2); i++)            // 如果儿子不足2个需要检查
488         {
489             int d = degree(child[i]);
490 
491             if( ret < d )
492             {
493                 ret = d;
494             }
495         }
496     }
497 
498     return ret;
499 }
500 
501 template < typename T >
502 int BSTree<T>::degree() const
503 {
504     return degree(dynamic_cast<BSTNode<T>*>(this->mRoot));
505 }
506 
507 template < typename T >
508 size_t BSTree<T>::getCount() const
509 {
510     return this->mCount;
511 }
512 
513 template <typename T>
514 void BSTree<T>::printTree(BSTNode<T> *tree, bool firstNode) const
515 {
516     if ( tree == nullptr )
517         return;
518 
519     size_t height = this->height();                // 树的高度
520     static bool *outTag = new bool[height]();    // 左边是否还有结点的标记,初始化为false
521     uint8_t static layer = 0;                    // 当前层数,根结点为第一层
522     uint8_t i;
523     ++layer;
524 
525     if ( layer > 1 )                    // 如果不是根节点需要输出特殊符号
526     {
527         for (i=1; i<layer-1; ++i )        // 根节点和最后一个结点不需要,所以从1至(layer-1)
528             if ( outTag[i] )            // 如果左边还有结点
529                 cout << "|       ";
530             else
531                 cout << "        ";
532 
533         if ( firstNode == true )        // 判断左右结点,非二叉树需要另外处理
534             cout << "L-------" << flush;
535         else
536             cout << "R-------" << flush;
537     }
538     cout << tree->mKey << endl;
539 
540     if ( (tree->mRight) != nullptr )    // 先输出右节点
541     {
542         if ( tree->mLeft != nullptr )    // 如果左边还有结点需要做标记
543             outTag[layer] = true;
544         printTree(tree->mRight, false);    // false表示当前是右节点
545     }
546 
547     if ( tree->mLeft != nullptr )
548     {
549         outTag[layer] = false;            // 左结点左边不再有结点,恢复默认标记
550         printTree(tree->mLeft, true);
551     }
552 
553     --layer;                            // 结点回溯时高度需要减1
554 }
555 
556 template <typename T>
557 void BSTree<T>::printTree() const
558 {
559     printTree(dynamic_cast<BSTNode<T>*>(this->mRoot), false);    // 作为根节点时,右参数无意义
560 }
561 
562 template < typename T >
563 const T& BSTree<T>::getRootKey() const
564 {
565     return this->mRoot->mKey;
566 }
567 
568 template < typename T >
569 BSTree<T>::~BSTree()
570 {
571     destroy();
572 }
573 
574 }
575 
576 #endif // BSTREE_H
View Code

Times.h

技术图片
 1 #ifndef TIMES_H
 2 #define TIMES_H
 3 
 4 #include <iostream>
 5 #include <sys/time.h>
 6 #ifdef _WIN32
 7 #include <windows.h>
 8 #endif
 9 
10 namespace LinWeiJie_lib
11 {
12 
13 // CPU频率计时器
14 #if defined (__i386__)
15 static __inline__ unsigned long long GetCycleCount(void)
16 {
17         unsigned long long int x;
18         __asm__ volatile("rdtsc":"=A"(x));
19         return x;
20 }
21 #elif defined (__x86_64__)
22 static __inline__ unsigned long long GetCycleCount(void)
23 {
24         unsigned hi,lo;
25         __asm__ volatile("rdtsc":"=a"(lo),"=d"(hi));
26         return (static_cast<unsigned long long>(lo))|(static_cast<unsigned long long>(hi)<<32);
27 }
28 #endif
29 
30 static void timing(bool b){
31     if(b) goto GET;
32     static struct timeval tv_begin, tv_end;
33     gettimeofday(&tv_begin, nullptr);
34 
35 #ifdef _WIN32
36     static LARGE_INTEGER li_freq, li_start, li_stop;
37     QueryPerformanceFrequency(&li_freq);
38     QueryPerformanceCounter(&li_start);
39 #endif
40 
41     static uint64_t t1 = GetCycleCount();
42 
43     std::cout << "启动计时..." << std::endl;
44     goto END;
45 
46 GET:
47     gettimeofday(&tv_end, nullptr);
48     std::cout << "Linux:  \\t" << std::fixed << (tv_end.tv_sec+tv_end.tv_usec/1000000.0)-(tv_begin.tv_sec+tv_begin.tv_usec/1000000.0) << " s" << std::endl;
49 
50 #ifdef _WIN32
51     QueryPerformanceCounter(&li_stop);
52     std::cout << "Windows:\\t" << (li_stop.QuadPart-li_start.QuadPart) * 1.0 / li_freq.QuadPart << " s" << std::endl;
53 #endif
54 
55     std::cout << "CPU:    \\t" << (GetCycleCount() - t1)/3800000000.0 << " s" << std::endl;
56 END:
57     ;
58 }
59 
60 static void timingStart()
61 {
62     timing(false);
63 }
64 
65 static void timingEnd()
66 {
67     timing(true);
68 }
69 
70 }
71 
72 #endif // TIMES_H
View Code

main.cpp

技术图片
 1 #include <iostream>
 2 #include <cmath>
 3 
 4 #include "BSTree.h"
 5 
 6 #include "Times.h"
 7 
 8 using namespace std;
 9 using namespace LinWeiJie_lib;
10 
11 int main(int argc, char* argv[])
12 {
13     uint16_t layer = 8;    // 结点最小层数
14 
15     if ( argc == 2 && atoi(argv[1])>0 )
16         layer = static_cast<uint8_t>(atoi(argv[1]));
17     else {
18         cout << "请输入结点最小层数,注意内存大小,结点层数上限为:" << log(RAND_MAX*RAND_MAX+1)/log(2) << endl;
19         cin >> layer;
20     }
21 
22     timingStart();                            // 启动计时
23 
24     cout << endl;
25 
26     uint64_t const count = (1ull<<layer)-1;    // 结点数
27     uint16_t speed;                            // 记录插入和删除的进度百分比(0~100)
28 
29     BSTree<uint64_t> *tree = new BSTree<uint64_t>();
30 
31     speed = 0;
32     srand(static_cast<unsigned int>(time(nullptr)));
33     while ( tree->getCount() < count )
34     {
35         tree->insert(static_cast<size_t>(rand()*rand()));    // 使用随机值插入;如果是顺序值,会退化成链表模式,且插入变慢
36 
37         if ( (tree->getCount()*100/count > speed) || (tree->getCount() == count) )    // 进度值出现变化或完成操作时才能输出
38         {
39             speed = static_cast<uint16_t>(tree->getCount()*100/count);
40             cout << "\\r已添加:" << setw(3) << speed << % << flush;
41         }
42     }
43     cout << endl;
44 
45     cout << "\\n前序遍历: ";
46     tree->preOrder();
47     cout << endl;
48 
49     cout << "\\n中序遍历: ";
50     tree->inOrder();
51     cout << endl;
52 
53     cout << "\\n后续遍历: ";
54     tree->postOrder();
55     cout << endl;
56 
57     cout << "\\n广度遍历:";
58     tree->levelOrder();
59     cout << endl;
60 
61     cout << "\\n最小值: " << tree->minimum();
62     cout << "\\n最大值: " << tree->maximum();
63     cout << "\\nheight = " << tree->height();
64     cout << "\\n结点数= " << tree->getCount();
65     cout << endl;
66 
67     cout << "\\n输出树形信息:" << endl;
68     tree->printTree();
69     cout << endl;
70 
71     speed = 0;
72     srand(static_cast<unsigned int>(time(nullptr)));
73     while ( tree->getCount() )
74     {
75         uint64_t node;
76 //        if ( tree->getCount()*100/count < 20 )            // 剩余量太少时,随机值命中有效结点的概率太低,从而导致删除缓慢
77             node = tree->getRootKey();
78 //        else
79 //            node = static_cast<size_t>(rand()*rand());
80 
81         tree->remove(node);
82 
83         if ( ((count-tree->getCount())*100/count > speed) || (tree->getCount() == count) )
84         {
85             speed = static_cast<uint16_t>((count-tree->getCount())*100/count);
86             cout << "\\r已删除:" << setw(3) << speed << % << flush;
87         }
88     }
89     cout << endl;
90 
91     tree->destroy();
92     delete tree;
93     tree = nullptr;
94 
95     cout << endl;
96     timingEnd();
97 
98     return 0;
99 }
View Code

 

以上是关于二叉树之二叉搜索树(BSTree)的主要内容,如果未能解决你的问题,请参考以下文章

二叉树之二叉搜索树的基本操作实现

数据结构 - 从二叉搜索树说到AVL树之二叉搜索树的操作与详解(Java)

树与二叉树之二--二叉树的性质与存储

[ 数据结构进阶 - C++ ] 二叉搜索树 BSTree

二叉树之不同的二叉搜索树[Buffalo]

搜索二叉树之字典实现