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