数据结构综合性实验:多种功能的平衡二叉排序树

  数据结构的期末作业是关于平衡二叉排序树的综合性实验,其中需要完成的功能有:

(1) 插入新结点 

(2) 前序、中序、后序遍历二叉树 (递归)

(3) 前序、中序、后序遍历的非递归算法 

(4) 层次遍历二叉树 

(5) 在二叉树中查找给定关键字(函数返回值为成功1,失败0) 

(6) 交换各结点的左右子树 

(7) 求二叉树的深度 

(8) 叶子结点数

(9) 删除某结点

  搞了两三天,上面的功能都实现了。而且我弄的是模板,兼容性也就相对强了一些。

  其实这对我只是一个锻炼而已,目测代码方面还有很多的地方可以改进,欢迎读者提出或指正。

  弄这个的时候发现一个比较矛盾的地方,就是其中会有树交换子树的操作。交换后,原来升序将会变成降序,反之亦然。所以,我在做的时候就不是单纯的给出交换子树的算法,而是在这个处理过后修改一个标记。初始化排序是按非降排序的,如果进行过一次倒置操作,树将以非升方式排序。这样就保持了二叉排序树的特性了。

 

View Code
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <algorithm>
  6 #include <cassert>
  7 #include <ctime>
  8 
  9 using namespace std;
 10 
 11 /********** simple stack template by Lyon   2012.11.24 **********/
 12 template <class T>
 13 class Stack {
 14     int maxSize, curSize;
 15     T *elem;
 16 public:
 17     void init() { // initialize stack
 18         maxSize = 16;
 19         curSize = 0;
 20         elem = (T *) malloc(maxSize * sizeof(T));
 21     }
 22     bool empty() { // whether the stack is empty
 23         return curSize == 0;
 24     }
 25     int size() { // get the size
 26         return curSize;
 27     }
 28     void push(T e) { // push e into stack
 29         while (curSize >= maxSize) {
 30             maxSize <<= 1;
 31             elem = (T *) realloc(elem, maxSize * sizeof(T));
 32         }
 33         elem[curSize++] = e;
 34     }
 35     void pop() { // pop out the top element
 36         assert(curSize > 0);
 37         curSize--;
 38     }
 39     T top() { // get the top element
 40         assert(curSize > 0);
 41         return elem[curSize - 1];
 42     }
 43 } ;
 44 /****************************************************************/
 45 
 46 /********** simple queue template by Lyon   2012.11.24 **********/
 47 template <class T>
 48 class Queue {
 49     struct Node {
 50         T elem;
 51         Node *next;
 52         Node (T &x) {
 53             elem = x;
 54             next = NULL;
 55         }
 56     } *head, *tail;
 57     int curSize;
 58 public:
 59     void init() { // initialize queue
 60         head = tail = NULL;
 61         curSize = 0;
 62     }
 63     bool empty() { // whether the queue is empty
 64         return curSize == 0;
 65     }
 66     int size() { // get the size
 67         return curSize;
 68     }
 69     void push(T &e) { // push e into queue
 70         if (head == NULL) {
 71             head = tail = new Node(e);
 72         } else {
 73             tail->next = new Node(e);
 74             tail = tail->next;
 75         }
 76         curSize++;
 77     }
 78     void pop() { // pop out the front element
 79         assert(head != NULL);
 80         Node *tmp = head;
 81         head = head->next;
 82         if (tail == tmp) tail = NULL;
 83         delete tmp;
 84         curSize--;
 85     }
 86     T front() { // get the front element
 87         assert(head != NULL);
 88         return head->elem;
 89     }
 90     T back() { // get the back element
 91         assert(tail != NULL);
 92         return tail->elem;
 93     }
 94 } ;
 95 /****************************************************************/
 96 
 97 /********** SBTree(short for Size-Balanced Tree) template by Lyon  2012.11.24 **********/
 98 template <class T>
 99 struct SBTNode { // size-balanced tree's node
100     int size, depth, leaf; // size - subtree's size, depth - subtree's depth, leaf - the number of leaf in subtree
101     T key;
102     SBTNode<T> *c[2]; // two child
103     SBTNode<T> (T k) {
104         key = k;
105         size = 1;
106         depth = 1;
107         leaf = 1;
108         c[0] = c[1] = NULL;
109     }
110 } ;
111 template <class T>
112 class SBTree { // size-balanced tree
113     SBTNode<T> *Root;
114     bool less; // the way of sort
115     void delTree(SBTNode<T> *&rt) { // delete the tree
116         if (!rt) return ;
117         delTree(rt->c[0]);
118         delTree(rt->c[1]);
119         delete rt;
120         rt = NULL;
121         less = false;
122     }
123     void rotate(SBTNode<T> *&x, bool left) { // rotate subtree x
124         bool right = !left;
125         SBTNode<T> *y = x->c[left];
126         x->c[left] = y->c[right];
127         y->c[right] = x;
128         y->size = x->size;
129         x->size = (x->c[0] ? x->c[0]->size : 0) + (x->c[1] ? x->c[1]->size : 0) + 1;
130         x->depth = max(x->c[0] ? x->c[0]->depth : 0, x->c[1] ? x->c[1]->depth : 0) + 1;
131         y->depth = max(y->c[0] ? y->c[0]->depth : 0, y->c[1] ? y->c[1]->depth : 0) + 1;
132         x->leaf = x->c[0] == NULL && x->c[1] == NULL ? 1 : (x->c[0] ? x->c[0]->leaf : 0) + (x->c[1] ? x->c[1]->leaf : 0);
133         x = y;
134     }
135     void maintain(SBTNode<T> *&rt, bool right) { // maintain subtree rt, if the right side of subtree is deeper
136         if (!rt->c[right] || !rt) return ;
137         bool left = !right;
138         int ls = rt->c[left] ? rt->c[left]->size : 0;
139         if (rt->c[right]->c[right] && rt->c[right]->c[right]->size > ls) rotate(rt, right);
140         else if (rt->c[right]->c[left] && rt->c[right]->c[left]->size > ls) rotate(rt->c[right], left), rotate(rt, right);
141         else return ;
142         maintain(rt->c[0], false);
143         maintain(rt->c[1], true);
144         maintain(rt, false);
145         maintain(rt, true);
146     }
147     void insert(SBTNode<T> *&rt, SBTNode<T> *x) { // insert x into subtree rt
148         if (!rt) {
149             rt = x;
150             return ;
151         }
152         rt->size++;
153         insert(rt->c[(x->key >= rt->key) ^ less], x);
154         maintain(rt, (x->key >= rt->key) ^ less);
155         rt->depth = max(rt->c[0] ? rt->c[0]->depth : 0, rt->c[1] ? rt->c[1]->depth : 0) + 1;
156         rt->leaf = rt->c[0] == NULL && rt->c[1] == NULL ? 1 : (rt->c[0] ? rt->c[0]->leaf : 0) + (rt->c[1] ? rt->c[1]->leaf : 0);
157     }
158     bool erase(SBTNode<T> *&rt, T k) { // erase key k in subtree rt
159         if (!rt) return false;
160         rt->size--;
161         if (k == rt->key) {
162             SBTNode<T> *t;
163             if (!rt->c[0] && !rt->c[1]) {
164                 delete rt;
165                 rt = NULL;
166             } else if (!rt->c[1]) {
167                 t = rt, rt = rt->c[0];
168                 delete t;
169             } else if (!rt->c[0]) {
170                 t = rt, rt = rt->c[1];
171                 delete t;
172             } else {
173                 t = rt->c[1];
174                 while (t->c[0]) t = t->c[0];
175                 rt->key = t->key;
176                 return erase(rt->c[1], t->key);
177             }
178         } else return erase(rt->c[(k > rt->key) ^ less], k);
179         if (rt) {
180             rt->depth = max(rt->c[0] ? rt->c[0]->depth : 0, rt->c[1] ? rt->c[1]->depth : 0) + 1;
181             rt->leaf = rt->c[0] == NULL && rt->c[1] == NULL ? 1 : (rt->c[0] ? rt->c[0]->leaf : 0) + (rt->c[1] ? rt->c[1]->leaf : 0);
182         }
183         return true;
184     }
185     void Traverse(SBTNode<T> *rt, int kind) { // recursive traverse : 1.pre 2.in 3.post
186         if (!rt) return ;
187         if (kind == 1) cout << rt->key << ends;
188         Traverse(rt->c[0], kind);
189         if (kind == 2) cout << rt->key << ends;
190         Traverse(rt->c[1], kind);
191         if (kind == 3) cout << rt->key << ends;
192     }
193     void nonRecursiveTraverse(int kind) { // non-recursive traverse : 1.pre 2.in 3.post
194         Stack<pair<SBTNode<T> *, int> > rec;
195         SBTNode<T> *cur;
196         int t;
197         rec.init();
198         rec.push(make_pair(Root, 1));
199         while (rec.size()) {
200             cur = rec.top().first;
201             t = rec.top().second;
202             rec.pop();
203             if (cur && t == kind) cout << cur->key << ends;
204             if (!cur || t >= 3 || t <= 0) continue;
205 //            cout << cur->key << '-' << t << ends;
206             rec.push(make_pair(cur, t + 1));
207             rec.push(make_pair(cur->c[t - 1], 1));
208         }
209     }
210     void reverse(SBTNode<T> *rt) { // reverse subtree rt
211         if (!rt) return ;
212         swap(rt->c[0], rt->c[1]);
213         reverse(rt->c[0]);
214         reverse(rt->c[1]);
215     }
216 public:
217     void init(bool cmp = false) { // initialize SBTree
218         Root = NULL;
219         less = cmp;
220     }
221     bool empty() {
222         return Root == NULL;
223     }
224     void delTree() { // delete SBTree
225         delTree(Root);
226         cout << "The Size-balanced Tree is deleted!" << endl;
227     }
228     void insert(T x) { // insert x into SBTree
229         SBTNode<T> *tmp = new SBTNode<T>(x);
230         insert(Root, tmp);
231         cout << "Element " << x << " Insert Successfully!" << endl;
232     }
233     bool erase(T k) { // erase k in SBTree
234         if (erase(Root, k)) {
235             cout << "Element " << k << " Erase Successfully!" << endl;
236             return true;
237         } else {
238             cout << "Element " << k << " not found!" << endl;
239             return false;
240         }
241     }
242     void preTraverse() { // output the pre-traverse array
243         cout << "The pre-Traverse array is:" << endl;
244         Traverse(Root, 1);
245         cout << endl;
246     }
247     void inTraverse() { // output the in-traverse array
248         cout << "The in-Traverse array is:" << endl;
249         Traverse(Root, 2);
250         cout << endl;
251     }
252     void postTraverse() { // output the post-traverse array
253         cout << "The post-Traverse array is:" << endl;
254         Traverse(Root, 3);
255         cout << endl;
256     }
257     void nonRecursivePreTraverse() { // in non-recursive way
258         cout << "The pre-Traverse array is (non-recursive):" << endl;
259         nonRecursiveTraverse(1);
260         cout << endl;
261     }
262     void nonRecursiveInTraverse() { // in non-recursive way
263         cout << "The in-Traverse array is (non-recursive):" << endl;
264         nonRecursiveTraverse(2);
265         cout << endl;
266     }
267     void nonRecursivePostTraverse() { // in non-recursive way
268         cout << "The post-Traverse array is (non-recursive):" << endl;
269         nonRecursiveTraverse(3);
270         cout << endl;
271     }
272     bool find(T key) { // find key value in SBTree
273         SBTNode<T> *p = Root;
274         while (true) {
275             if (!p) return false;
276             if (key == p->key) return true;
277             if ((key < p->key) ^ less) p = p->c[0];
278             else p = p->c[1];
279         }
280     }
281     int depth() {
282         return Root->depth;    // the depth of SBTree
283     }
284     int leaves() {
285         return Root->leaf;    // the number of leaf in SBTree
286     }
287     void reverse() { // reverse SBTree
288         less = !less;
289         reverse(Root);
290         cout << "Tree is reversed!" << endl;
291     }
292     void nonRecursiveReverseDFS() { // in non-recursive way
293         less = !less;
294         Stack<pair<SBTNode<T> *, int> > rec;
295         SBTNode<T> *cur;
296         int t;
297         rec.init();
298         rec.push(make_pair(Root, 1));
299         while (rec.size()) {
300             cur = rec.top().first;
301             t = rec.top().second;
302             rec.pop();
303             if (!cur || t >= 3 || t <= 0) continue;
304             if (t == 1) swap(cur->c[0], cur->c[1]);
305 //            cout << cur->key << '-' << t << ends;
306             rec.push(make_pair(cur, t + 1));
307             rec.push(make_pair(cur->c[t - 1], 1));
308         }
309     }
310     void nonRecursiveReverseBFS() {
311         less = !less;
312         Queue<SBTNode<T> *> tmp;
313         SBTNode<T> *cur;
314         tmp.init();
315         tmp.push(Root);
316         while (tmp.size()) {
317             cur = tmp.front();
318             swap(cur->c[0], cur->c[1]);
319             if (cur->c[0]) tmp.push(cur->c[0]);
320             if (cur->c[1]) tmp.push(cur->c[1]);
321         }
322         cout << "Tree is reversed!" << endl;
323     }
324     void levelTraverse() { // level traverse
325         Queue<SBTNode<T> *> q;
326         cout << "The level traverse array is:" << endl;
327         q.init();
328         q.push(Root);
329         SBTNode<T> *cur;
330         while (q.size()) {
331             cur = q.front();
332             q.pop();
333             cout << cur->key << ends;
334             if (cur->c[0]) q.push(cur->c[0]);
335             if (cur->c[1]) q.push(cur->c[1]);
336         }
337         cout << endl;
338     }
339 } ;
340 /*************************************************************************************/
341 
342 
343 
344 #define REP(i, n) for (int i = 0; i < n; i++)
345 SBTree<int> SBT;
346 
347 int main() {
348     int n, e, op;
349     char buf[100];
350 
351     SBT.init();
352     cout << "请输入树的节点个数:";
353     cin >> n;
354     cout << "请输入" << n << "个整数:";
355     REP(i, n) {
356         cin >> e;
357         SBT.insert(e);
358     }
359     system("pause > nul");
360     system("cls");
361     while (true) {
362         while (true) {
363             cout << "━━━━━━━━━━━━━━━━━┓\n";
364             cout << "  1.查看树的前中后序及层次遍历    ┃\n";
365             cout << "  2.查看树的前中后序遍历(非递归)┃\n";
366             cout << "  3.查找树的结点                  ┃\n";
367             cout << "  4.查看树的深度和叶子结点个数    ┃\n";
368             cout << "  5.交换树的左右子树              ┃\n";
369             cout << "  6.插入新的结点                  ┃\n";
370             cout << "  7.删除结点                      ┃\n";
371             cout << "  8.退出程序                      ┃\n";
372             cout << "━━━━━━━━━━━━━━━━━┛\n";
373             cout << "请输入操作编号:";
374             cin >> op;
375             if (0 <= op && op <= 8) break;
376             cout << "输入错误,请重新输入!" << endl;
377             system("pause > nul");
378             system("cls");
379         }
380         switch (op) {
381         case 1:
382             if (SBT.empty()) cout << "当前树为空树" << endl;
383             else {
384                 SBT.preTraverse();
385                 SBT.inTraverse();
386                 SBT.postTraverse();
387                 SBT.levelTraverse();
388             }
389             break;
390         case 2:
391             if (SBT.empty()) cout << "当前树为空树" << endl;
392             else {
393                 SBT.nonRecursivePreTraverse();
394                 SBT.nonRecursiveInTraverse();
395                 SBT.nonRecursivePostTraverse();
396             }
397             break;
398         case 3:
399             cout << "请输入需要查找结点的值:";
400             cin >> e;
401             if (SBT.find(e)) cout << "查找成功,该结点存在!" << endl;
402             else cout << "查找失败,该结点不存在!" << endl;;
403             break;
404         case 4:
405             cout << "树的深度为:" << SBT.depth() << endl;
406             cout << "树的叶子结点个数为:" << SBT.leaves() << endl;
407             break;
408         case 5:
409             cout << "确定要交换树的左右结点吗?(交换以后,元素升降序将改变)" << endl << "按'Y'键后回车继续:";
410             cin >> buf;
411             strlwr(buf);
412             if (buf[0] == 'y') {
413                 SBT.reverse();
414                 cout << "操作成功" << endl;
415             } else cout << "已放弃操作" << endl;
416             break;
417         case 6:
418             cout << "请输入新结点的值:";
419             cin >> e;
420             SBT.insert(e);
421             cout << "结点已成功插入" << endl;
422             break;
423         case 7:
424             if (SBT.empty()) cout << "当前树为空树,不能进行删除操作" << endl;
425             else {
426                 SBT.nonRecursiveInTraverse();
427                 cout << "请输入要删除的结点的值: ";
428                 cin >> e;
429                 if (!SBT.erase(e)) cout << "操作失败,该结点不存在" << endl;
430                 else cout << "操作成功" << endl;
431             }
432             break;
433         case 8:
434             SBT.delTree();
435             cout << "操作成功,可以安全退出!" << endl;
436             system("pause > nul");
437             return 0;
438         default:
439             cout << "出现异常!" << endl;
440             return -1;
441         }
442         system("pause > nul");
443         system("cls");
444     }
445 }

 

——written by Lyon

原文地址:https://www.cnblogs.com/LyonLys/p/2012_11_24_Lyon.html