1 #include <iostream>
2 #include <stack>
3 using namespace std;
4
5 template<typename T>
6 struct BinaryNode
7 {
8 T element;
9 BinaryNode<T> *left;
10 BinaryNode<T> *right;
11
12 BinaryNode(const T &theElement, BinaryNode *lt, BinaryNode *rt)
13 : element(theElement), left(lt), right(rt) {}
14 };
15
16
17 template<typename T>
18 class BinarySearchTree
19 {
20 public:
21 BinarySearchTree() {
22 root = nullptr;
23 }
24 BinarySearchTree(const BinarySearchTree& rhs) { //复制构造函数
25 root = clone(rhs.root);
26 }
27 ~BinarySearchTree();
28
29 const T &findMin() const {
30 return findMin(root)->element;
31 }
32 const T &findMax() const {
33 return findMax(root)->element;
34 }
35
36 bool contains(const T& x) const;
37 T& getNode(const T& e) { //得到元素为e的结点
38 return getNode(e, root)->element;
39 }
40
41 bool isEmpty() const {
42 if (root == nullptr)
43 return true;
44 return false;
45 }
46 void PreprintTree() const {
47 PreprintTree(root);
48 }
49
50 void InprintTree() const {
51 InprintTree(root);
52 }
53
54 void PostprintTree() const {
55 PostprintTree(root);
56 }
57
58 void LevelprintTree() const {
59 LevelprintTree(root);
60 }
61
62 void PreprintTree_N() const {
63 PreprintTree_N(root);
64 }
65
66 void InprintTree_N() const {
67 InprintTree_N(root);
68 }
69
70 void PostprintTree_N() const {
71 PostprintTree_N(root);
72 }
73
74 void DisplayTreeShape(int level = 1) const {
75 DisplayTreeShape(root, level);
76 }
77
78 void makeEmpty();
79 void insert(const T &x);
80 void remove(const T &x);
81 int Depth();
82 int CountLeaf() {
83 BinaryNode<T> *p = root;
84 int count = 0;
85 CountLeaf(p, count);
86 return count;
87 }
88
89 const BinarySearchTree& operator = (const BinarySearchTree& rhs);
90
91 private:
92
93 BinaryNode<T> *root; //指向树根结点的指针
94
95 void insert(const T & x, BinaryNode<T> * & t);
96 void remove(const T & x, BinaryNode<T> * & t);
97 BinaryNode<T> * findMin(BinaryNode<T> *t) const;
98 BinaryNode<T> * findMax(BinaryNode<T> *t ) const;
99
100 bool contains(const T & x, BinaryNode<T> *t) const;
101 BinaryNode<T> * getNode(const T &x, BinaryNode<T> *t);
102
103 void makeEmpty( BinaryNode<T> * & t );
104 //利用 递归 算法 计算树的 深度
105 int Depth( BinaryNode<T> * t, int level, int &depth);
106 //利用 递归 算法 计算树的 高度
107 void CountLeaf(BinaryNode<T> * t, int &count);
108
109
110 void PreprintTree( BinaryNode<T> * t ) const; //先序遍历
111 void InprintTree( BinaryNode<T> *t ) const; //中序遍历
112 void PostprintTree( BinaryNode<T> * t ) const; //后序遍历
113 void LevelprintTree( BinaryNode<T> * t) const; //层次遍历
114
115 void PreprintTree_N( BinaryNode<T> * t) const; //非递归先序遍历
116 void InprintTree_N( BinaryNode<T> * t) const; //非递归中序遍历二叉树
117 void PostprintTree_N( BinaryNode<T> * t) const; //非递归后序遍历二叉树
118 void DisplayTreeShape(BinaryNode<T> *bt, int level) const; //二叉树的树形显示算法
119
120
121 BinaryNode<T> * clone( BinaryNode<T> * t ) const;
122 };
123
124 template<typename T>
125 bool BinarySearchTree<T>::contains(const T& x) const
126 {
127 return contains(x, root);
128 }
129
130 template<typename T>
131 bool BinarySearchTree<T>::contains(const T & x, BinaryNode<T> *t) const
132 {
133 if (t == nullptr)
134 return false;
135 else if (x < t->element) // x 小, 说明应该在左边找
136 return contains(x, t->left);
137 else if (t->element < x) // x 大, 说明应该在右面找
138 return contains(x, t->right);
139 else
140 return true;
141 }
142
143 template<typename T>
144 BinaryNode<T>* BinarySearchTree<T>::getNode(const T & x, BinaryNode<T> *t)
145 {
146 if (t == nullptr)
147 return nullptr;
148 else if (x < t->element)
149 return getNode(x, t->left);
150 else if (t->element < x)
151 return getNode(x, t->right);
152 return t;
153 }
154
155
156 //findMin--返回指向树中包含最小元的结点的指针
157 template<typename T>
158 BinaryNode<T> * BinarySearchTree<T>::findMin(BinaryNode<T> *t) const
159 {
160 if (t == nullptr)
161 return nullptr;
162 if (t->left == nullptr)
163 return t;
164 return findMin(t->left);
165 }
166
167 template<typename T>
168 BinaryNode<T>* BinarySearchTree<T>::findMax(BinaryNode<T> *t) const
169 {
170 if (t != nullptr)
171 while (t->right != nullptr) {
172 t = t->right;
173 }
174 return t;
175 }
176
177 template<typename T>
178 void BinarySearchTree<T>::insert(const T &x)
179 {
180 insert(x, root);
181 }
182
183 /************************************************************************/
184 /* x is the item to insert */
185 /* t is the node that roots the subtree*/
186 /* Set the new root of the subtree*/
187 ///* 只有当一个新树叶生成时候,t才改变.
188 ///* t 是到p->left或p->right的引用.==> 意味着p->left或p->right将会改变为指向新结点.
189 /************************************************************************/
190 template<typename T>
191 void BinarySearchTree<T>::insert(const T & x, BinaryNode<T> * & t)
192 {
193 if (t == nullptr) //没有结点,在该位置处添加新结点
194 t = new BinaryNode<T>(x, nullptr, nullptr);
195 else if (x < t->element) //x 小, 在左子树查询
196 insert(x, t->left);
197 else if (t->element < x) //x 大, 在右子树查询
198 insert(x, t->right);
199 else; //Duplicate, do nothing;
200 }
201
202 template<typename T>
203 void BinarySearchTree<T>::remove(const T &x)
204 {
205 remove(x, root);
206 }
207
208 /************************************************************************/
209 /* x is item to remove */
210 /* t is the node that roots the subtree */
211 /* Set the new root of the subtree */
212 /* 1.结点是一片树叶时 -- 可被立即删除*/
213 /* 2.结点有一个儿子, 则该结点可以在其父节点调整他的链 以绕过该结点后被删除 */
214 /* 3.结点有两个儿子, 则其右子树的最小数据代替该结点的数据,并递归删除那个结点 */
215 /* 注: 右子树中的最小的结点不可能有左结点 */
216 /************************************************************************/
217 template<typename T>
218 void BinarySearchTree<T>::remove(const T &x, BinaryNode<T> * & t)
219 {
220 if (t == nullptr) return; //Item not found; do nothing
221 if (x < t->element) //x 小,在左子树递归查找
222 remove(x, t->left);
223 else if (t->element < x) //x 大,在右子树递归查找
224 remove(x, t->right);
225 else if (t->left != nullptr && t->right != nullptr) //two children
226 {
227 //在右子树中查找最小数据代替该结点数据.;
228 t->element = findMin(t->right)->element;
229 remove(t->element, t->right); //删除该结点
230 }
231 else //只有一个结点或是树叶. 调整它的链,以绕过该结点后被删除.
232 {
233 BinaryNode<T> *oldNode = t;
234 t = (t->left != nullptr) ? t->left : t->right;
235 delete oldNode;
236 }
237 }
238
239 /************************************************************************/
240 ///* Destructor for the tree
241 /************************************************************************/
242 template<typename T>
243 BinarySearchTree<T>::~BinarySearchTree()
244 {
245 makeEmpty();
246 }
247
248 template<typename T>
249 void BinarySearchTree<T>::makeEmpty() //公有函数
250 {
251 makeEmpty(root);
252 }
253
254 /************************************************************************/
255 ///* Internal method to make subtree empty -- 私有函数
256 /************************************************************************/
257 template<typename T>
258 void BinarySearchTree<T>::makeEmpty(BinaryNode<T> * & t)
259 {
260 if (t != nullptr)
261 {
262 makeEmpty(t->left);
263 makeEmpty(t->right);
264 delete t;
265 }
266 t = nullptr;
267 }
268
269 /************************************************************************/
270 ///* Deep copy
271 /************************************************************************/
272 template<typename T>
273 const BinarySearchTree<T>& BinarySearchTree<T>::operator = (const BinarySearchTree &rhs)
274 {
275 if (this != &rhs) {
276 makeEmpty();
277 root = clone(rhs.root);
278 }
279 return *this;
280 }
281
282 /************************************************************************/
283 ///* Internal method to clone subtree. -- 递归复制结点
284 /************************************************************************/
285 template<typename T>
286 BinaryNode<T>* BinarySearchTree<T>::clone(BinaryNode<T> * t) const
287 {
288 if (t == nullptr)
289 return nullptr;
290 return new BinaryNode<T>( t->element, clone(t->left), clone(t->right) );
291 }
292
293 //利用递归计算树的深度
294 template<typename T>
295 int BinarySearchTree<T>::Depth()
296 {
297 BinaryNode<T> *t = root;
298 int depth = 0;
299 if (root == nullptr)
300 return 0;
301 Depth(t, 1, depth);
302 return depth;
303 }
304
305 //由public的函数Depth调用, 完成树的深度的计算,p是根结点,Level是层,depth用来返回树的深度
306 template<typename T>
307 int BinarySearchTree<T>::Depth(BinaryNode<T> *t, int level, int &depth)
308 {
309 if (level > depth) depth = level; //层数
310 if (t->left) Depth(t->left, level + 1, depth); //递归遍历左子树,且层数加1
311 if (t->right) Depth(t->right, level + 1, depth); //递归遍历右子树, 且层数加1
312 return 0;
313 }
314
315 template<typename T>
316 //利用 递归 算法 计算树的 高度
317 void BinarySearchTree<T>::CountLeaf(BinaryNode<T> * t, int &count)
318 {
319 if (t == nullptr) return; //为空时,退出
320
321 // CountLeaf(t->left, count);
322 // CountLeaf(t->right, count);
323 if (!(t->left) && !(t->right)) { //儿子为空时
324 count++;
325 }
326 CountLeaf(t->left, count);
327 CountLeaf(t->right, count);
328 }
329
330
331 /************************************************************************/
332 ///* printTree --- 前序遍历
333 /************************************************************************/
334 template<typename T>
335 void BinarySearchTree<T>::PreprintTree(BinaryNode<T> * t) const
336 {
337 if (t != nullptr) {
338 cout << t->element << ' ';
339 PreprintTree(t->left);
340 PreprintTree(t->right);
341 }
342 }
343
344 //中序遍历
345 template<typename T>
346 void BinarySearchTree<T>::InprintTree(BinaryNode<T> * t ) const
347 {
348 if (t != nullptr) {
349 InprintTree(t->left);
350 cout << t->element << ' ';
351 InprintTree(t->right);
352 }
353 }
354
355 //后序遍历
356 template<typename T>
357 void BinarySearchTree<T>::PostprintTree(BinaryNode<T> * t) const
358 {
359 if (t != nullptr) {
360 PostprintTree(t->left);
361 PostprintTree(t->right);
362 cout << t->element << ' ';
363 }
364 }
365
366 //利用队列Queue层次遍历二叉树
367 template<typename T>
368 void BinarySearchTree<T>::LevelprintTree( BinaryNode<T> * t) const
369 {
370 const int maxn = 1024;
371 BinaryNode<T> *Queue[maxn]; //一维数组作为队列
372 BinaryNode<T> *tmp;
373 int front = 0, rear = 0; //队列初始为空
374 if (root) {
375 Queue[rear++] = root; //二叉树的根结点指针入队列
376 while (front != rear)
377 {
378 tmp = Queue[front++]; //队首的元素出队列
379 if (tmp) cout << tmp->element << ' '; //输出结点值
380 if (tmp->left) Queue[rear++] = tmp->left;
381 if (tmp->right) Queue[rear++] = tmp->right;
382 }
383 }
384 }
385
386 //先序遍历
387 template<typename T>
388 void BinarySearchTree<T>::PreprintTree_N( BinaryNode<T> * t) const //非递归先序遍历
389 {
390 const int maxn = 1024;
391 BinaryNode<T> *Stack[maxn];
392 int top = 0;
393 BinaryNode<T> *tmp = root; //将根结点的指针赋值给tmp
394
395 // cout << "Debug :\n";
396 while (tmp || top != 0)
397 {
398 // cout << "debug : \n";
399 while (tmp) {
400 cout << tmp->element << ' ';
401 Stack[top++] = tmp; //右孩子入栈
402 tmp = tmp->left; //一直递归到最左的结点
403 }
404 if (top) { //栈不为空, 从栈中取出一个结点指针
405 tmp = Stack[--top];
406 tmp = tmp->right;
407 }
408 }
409 }
410
411 //中序非递归遍历二叉树 (LDR)
412 template<typename T>
413 void BinarySearchTree<T>::InprintTree_N( BinaryNode<T> * t) const //非递归中序遍历二叉树
414 {
415 const int maxn = 1024;
416 BinaryNode<T> *Stack[maxn];
417 int top = 0;
418 BinaryNode<T> *tmp = root;
419
420 while (tmp || top != 0)
421 {
422 while (tmp) { //迭代到最左的子树
423 Stack[top++] = tmp; //左子树入栈
424 tmp = tmp->left;
425 }
426 if (top) {
427 tmp = Stack[--top]; //出栈最左的子树
428 cout << tmp->element << ' '; //输出该元素
429 tmp = tmp->right; //并指向右结点开始迭代
430 }
431 }
432
433 }
434
435 //非递归后序遍历二叉树 (LRD)
436 template<typename T>
437 void BinarySearchTree<T>::PostprintTree_N( BinaryNode<T> * t) const
438 {
439 const int maxn = 1024;
440 struct Mystack {
441 BinaryNode<T> * link;
442 int flag;
443 };
444
445 Mystack Stack[maxn];
446 BinaryNode<T> * p = root, *tmp;
447
448 if (root == nullptr) return;
449
450 int top = -1, //栈顶初始化
451 sign = 0; //为结点tmp 的标志量
452
453 while ( p != nullptr || top != -1)
454 {
455 while (p != nullptr) //遍历到最左
456 {
457 Stack[++top].link = p; //并且一直入栈
458 Stack[top].flag = 1; //设置flag为第一次入栈
459 p = p->left;
460 }
461
462 if (top != -1)
463 {
464 tmp = Stack[top].link;
465 sign = Stack[top].flag;
466 top--; //出栈
467
468 if (sign == 1) //结点第一次进栈
469 {
470 top++;
471 Stack[top].link = tmp;
472 Stack[top].flag = 2; //标记为第二次出栈
473 p = tmp->right;
474 }
475 else { //第二次出栈就输出
476 cout << tmp->element << ' '; //访问该结点数据域
477 p = nullptr;
478 }
479 }
480
481 }
482
483 }
484
485 //树形显示二叉树,也是中序遍历
486 template<typename T>
487 void BinarySearchTree<T>::DisplayTreeShape(BinaryNode<T> *bt, int level) const
488 {
489 if (bt) //二叉树的树形显示算法
490 {
491 cout << endl;
492 for (int i = 0; i < level - 1; i++)
493 cout << " "; //确保在第level列显示结点
494 cout << bt->element; //显示结点
495 DisplayTreeShape(bt->left, level - 1); //空二叉树不显示
496 // cout << endl; //显示右子树
497 DisplayTreeShape(bt->right, level + 2); //显示左子树
498 }
499 }
500
501 int main()
502 {
503 // srand((unsigned)time(nullptr));
504 int testData, t = 0;
505 BinarySearchTree<int> test;
506 cout << "输入数字个数: \n";
507 cin >> t;
508 cout << "输入数字: \n";
509 while (t--)
510 {
511 testData = rand() % 500 + 1;
512 test.insert(testData);
513 }
514 cout << "\n全部元素为: \n";
515 test.PreprintTree();
516
517 cout << endl;
518 // cin >> testData; //不符合查找二叉树
519 // test.getNode(testData) = 10000;
520
521
522 cout << "\nMax = " << test.findMax() << endl;
523 cout << "Min = " << test.findMin() << endl;
524
525 cout << "输入查找元素: \n";
526 cin >> testData;
527 cout << "是否包含 " << testData << " : " << test.contains(testData) << endl;
528 test.PreprintTree();
529
530 cout << endl;
531 cout << "输入删除元素: \n";
532 cin >> testData;
533 test.remove(testData);
534
535 cout << "\n树的高度: " << test.Depth() << endl;
536 cout << "\n叶子的个数: " << test.CountLeaf() << endl;
537 cout << endl;
538
539 cout << "先序遍历树元素: \n";
540 test.PreprintTree();
541
542 cout << "\n\n中序遍历树元素: \n";
543 test.InprintTree();
544
545 cout << "\n\n后序遍历树元素: \n";
546 test.PostprintTree();
547
548 cout << "\n\n层次遍历树元素: \n";
549 test.LevelprintTree();
550
551 cout << "\n\n先序遍历树元素(非递归): \n";
552 test.PreprintTree_N();
553
554 cout << "\n\n中序遍历树元素(非递归): \n";
555 test.InprintTree_N();
556
557 cout << "\n\n后序遍历树元素(非递归): \n";
558 test.PostprintTree_N();
559
560 cout << "\n\n二叉树的树形显示算法: \n";
561 test.DisplayTreeShape(43);
562
563 cout << endl;
564 return 0;
565 }