用C++来完成一个二叉树,并实现一些简单功能

首先是目标

1、先序遍历此树
2、中序遍历此树
3、后序遍历此树
4、打印二叉树
5、层序遍历此树
6、二叉树中的节点个数
7、二叉树中叶子节点的个数
8、显示二叉树中叶子节点
9、树的深度
10、求双亲
11、删除以x为根元素的子树
12、交换二叉树左右子树
13、求路径

整个程序大概摸了5天(虽然只有课后才写一会)

感觉比较难的地方有以下几个

4、打印二叉树

13、求路径

求路径这个我坐了两个小时写完了,本来是有两种思路,1、从根节点开始深度优先遍历,直到找到为止(用栈实现);2、从目标节点开始一层层寻找双亲,把找到的双亲存到数组里,最后反向输出

因为比较爱偷懒,不想动脑子,所以还是先写出了第二种,第一种还是有空再慢慢摸吧

打印二叉树真是把我折磨的欲仙欲死,五天时间有两天是花在这上面,当然我是最后才去写这个打印二叉树。在网上看了很多人的代码,感觉还是学不来,于是自己想了一个蠢办法,就是把整个二叉树变成最大深度的完全二叉树,没有节点的地方补#,然后存在一个数组里面,最后打印这个数组,想办法想了一天,然后改bug改了一天,虽然最后还是摸出来了。

 

接下来是代码:

主函数:

#include<iostream>
#include "BiTree.h"

using namespace std;
int main()
{
    cout << "请按前序输入二叉树中的元素: " << endl;
    BiTree<char> bit;
    char x;
    bool flag = 1;
    while (flag)
    {
        cout << endl;
        cout << "0、退出程序" << endl;
        cout << "1、先序遍历此树" << endl;//OK
        cout << "2、中序遍历此树" << endl;//OK
        cout << "3、后序遍历此树" << endl;//OK
        cout << "4、打印二叉树" << endl;//OK
        cout << "5、层序遍历此树" << endl;//OK
        cout << "6、二叉树中的节点个数" << endl;//OK
        cout << "7、二叉树中叶子节点的个数" << endl;//OK
        cout << "8、显示二叉树中叶子节点" << endl;//OK
        cout << "9、树的深度" << endl;//OK
        cout << "10、求双亲" << endl;//OK
        cout << "11、删除以x为根元素的子树" << endl;//OK
        cout << "12、交换二叉树左右子树" << endl;//OK
        cout << "13、求路径" << endl;//OK
        cout << endl;
        cout << "请输入你要进行的操作:";
        int ch;
        cin >> ch;
        if (ch == 0)
        {
            flag = 0;
        }
        else if (ch == 1)
        {
            bit.PreOrder();
            cout << endl;
        }
        else if (ch == 2)
        {
            bit.InOrder();
            cout << endl;
        }
        else if (ch == 3)
        {
            bit.PostOrder();
            cout << endl;
        }
        else if (ch == 4)
        {
            bit.printTree();
        }
        else if (ch == 5)
        {
            bit.LevelOrder();
            cout << endl;
        }
        else if (ch == 6)
        {
            cout << "节点个数为: " << bit.getAll();
            cout << endl;
        }
        else if (ch == 7)
        {
            cout << "叶子节点个数为:" << bit.getCount();
            cout << endl;
        }
        else if (ch == 8)
        {
            bit.showLeaf();
            cout << endl;
        }
        else if (ch == 9)
        {
            cout << "树的深度为:" << bit.Depth();
            cout << endl;
        }
        else if (ch == 10)
        {
            cout << "请输入需要查找的节点: " << endl;
            cin >> x;
            if (bit.searchParent(x) == '#')
            {
                cout << "没有找到双亲节点或者没有双亲节点" << endl;
            }
            else
            {
                cout << "双亲节点为:" << bit.searchParent(x) << endl;
            }
        }
        else if (ch == 11)
        {
            cout << "请输入需要删除的元素: ";
            cin >> x;
            bit.deleteNode(x);
            cout << endl;
        }
        else if (ch == 12)
        {
            bit.Swap();
            cout << "左右子树交换成功!" << endl;
        }
        else if (ch == 13)
        {
            cout << "请输入需要查找路径的节点:";
            cin >> x;
            bit.getRoute(x);
            cout << endl;
        }
        else
        {
            cout << "error" << endl;
        }
        cout << "-------------------------------------------------" << endl;
    }
}

方法类

  1 #pragma once
  2 #include <iostream>
  3 using namespace std;
  4 
  5 template <typename DataType>
  6 struct BiNode
  7 {
  8     DataType data;
  9     BiNode<DataType>* lchild = nullptr, * rchild = nullptr;
 10 };
 11 template <typename DataType>
 12 class BiTree
 13 {
 14 public:
 15     BiTree() { root = Creat(); }
 16     ~BiTree() { Release(root); }
 17     void PreOrder() { PreOrder(root); }       //前序遍历
 18     void InOrder() { InOrder(root); }         //中序遍历
 19     void PostOrder() { PostOrder(root); }     //后续遍历
 20     void LevelOrder();                        //层序遍历
 21     int getCount() { return getCount(root); } //求叶子节点的个数
 22     int getAll() { return getAll(root); }     //求节点个数
 23     void showLeaf() { showLeaf(root); }       //显示叶子节点
 24     int Depth() { return Depth(root); }       //求深度
 25     char searchParent(char a) { return searchParent(a, root); }//找双亲
 26     int max(int a, int b);
 27     void getRoute(char x) { getRoute(x, root); }//求路径
 28     void deleteNode(char x);                  //删除节点
 29     void Swap();                              //交换左右子树
 30     void printTree() { printTree(root); }     //打印二叉树
 31 private:
 32     BiNode<DataType>* Creat();
 33     void Release( BiNode<DataType>* bt );
 34     void PreOrder(BiNode<DataType>* bt);
 35     void InOrder(BiNode<DataType>* bt);
 36     void PostOrder(BiNode<DataType>* bt);
 37     int getCount(BiNode<DataType>* bt);    
 38     int getAll(BiNode<DataType>* bt);
 39     void showLeaf(BiNode<DataType>* bt);
 40     int Depth(BiNode<DataType>* bt);
 41     BiNode<DataType>* root;
 42     char searchParent(char a, BiNode<DataType>* bt);
 43     void getRoute(char x, BiNode<DataType>* bt);
 44     void printTree(BiNode<DataType>* bt);
 45 };
 46 template <typename DataType>
 47 void BiTree<DataType>::printTree(BiNode<DataType>* bt)
 48 {
 49     int wid = Depth();
 50     int length=0;
 51     for (int i = 0; i < wid; i++)
 52     {
 53         length += (1 << i);
 54     }
 55     char* a = new char[length];
 56     for (int i = 0; i < length; i++)
 57         a[i] = '*';
 58     BiNode<DataType>* Q[100], * q = nullptr;
 59     int front = -1, rear = -1;
 60     Q[++rear] = bt;
 61     
 62     for (int i = 1; i <= wid; i++)
 63     {
 64         for (int j = 1; j <= (1 << (i - 1)); j++)
 65         {
 66             int number = (1 << (i - 1)) + j - 2;
 67             if (a[number] == '#')
 68             {
 69                 if (i != wid)
 70                 {
 71                     a[(number + 1) * 2 - 1] = '#';
 72                     a[(number + 1) * 2] = '#';
 73                 }
 74             }
 75             else
 76             {
 77                 if (front != rear)
 78                 {
 79                     q = Q[++front];
 80                     a[number] = q->data;
 81                     if (q->lchild != nullptr)
 82                     {
 83                         Q[++rear] = q->lchild;
 84                     }
 85                     else
 86                     {
 87                         if (i != wid)
 88                         {
 89                             a[(number + 1) * 2 - 1] = '#';
 90                         }
 91                     }
 92                     if (q->rchild != nullptr)
 93                     {
 94                         Q[++rear] = q->rchild;
 95                     }
 96                     else
 97                     {
 98                         if (i != wid)
 99                         {
100                             a[(number+1)*2]='#';
101                         }
102                     }
103                 }
104             }
105         }
106     }
107     for (int i = 1; i <= wid; i++)
108     {
109         for (int j = 1; j <= (1 << (i - 1)); j++)
110         {
111             int number = (1 << (i - 1)) + j - 2;
112             if (j == 1)
113             {
114                 if (i == 1)
115                 {
116                     for (int k = 0; k < (1 << (wid - 2)); k++)
117                     {
118                         cout << " ";
119                     }
120                 }
121                 else
122                 {
123                     for (int k = 0; k < (1 << (wid - 2)) - (1 << (i - 2)); k++)
124                     {
125                         cout << " ";
126                     }
127                 }
128             }
129             cout << a[number];
130             if (j&1)
131             {
132                 cout << " ";
133             }
134         }
135         cout << endl;
136     }
137 }
138 template <typename DataType>
139 void BiTree<DataType>::Swap()
140 {
141     BiNode<DataType>* bt = root;
142     BiNode<DataType>* temporary = nullptr;
143 
144     BiNode<DataType>* Q[100], * q = nullptr;
145     int front = -1, rear = -1;
146     if (root == nullptr) return;//二叉树为空
147     Q[++rear] = root;
148     while (front != rear)
149     {
150         q = Q[++front];
151         bt = q;
152         temporary = bt->lchild;
153         bt->lchild = bt->rchild;
154         bt->rchild = temporary;
155         if (q->lchild != nullptr) Q[++rear] = q->lchild;
156         if (q->rchild != nullptr) Q[++rear] = q->rchild;
157     }
158 }
159 template <typename DataType>
160 void BiTree<DataType>::deleteNode(char x)
161 {
162     BiNode<DataType>* bt=root;
163     if (root == nullptr) return;
164     else
165     {
166         BiNode<DataType>* Q[100], * q = nullptr;
167         int front = -1, rear = -1;
168         Q[++rear] = root;
169         while (front != rear)
170         {
171             q = Q[++front];
172             bt = q;
173             if (q->lchild != nullptr && q->lchild->data == x)
174             {
175                 bt = q->lchild;
176                 Release(bt);
177                 q->lchild = nullptr;
178                 return;
179             }
180             if (q->rchild != nullptr && q->rchild->data == x)
181             {
182                 bt = q->rchild;
183                 Release(bt);
184                 q->rchild = nullptr;
185                 return;
186             }
187             if (q->lchild != nullptr) Q[++rear] = q->lchild;
188             if (q->rchild != nullptr) Q[++rear] = q->rchild;
189         }
190     }
191 }
192 template <typename DataType>
193 void BiTree<DataType>::getRoute(char x, BiNode<DataType>* bt)//两种方法,1、从节点处不断寻找双亲节点(队列);2、从根节点开始按深度优先遍历(栈)
194 {
195     char a[20];
196     int count = 0;
197     char b;
198     if (bt == nullptr)
199     {
200         cout << "二叉树为空" << endl;
201         return;
202     }
203     else
204     {
205         bool flag = true;
206         a[count++] = x;
207         while (flag)
208         {
209             if (searchParent(a[count-1],bt) != '#')
210             {
211                 b = searchParent(a[count - 1],bt);
212                 a[count++] = b;
213             }
214             else
215             {
216                 flag = false;
217             }
218         }
219         for (int i = count-1; i >=0; i--)
220         {
221             if (i !=0)
222             {
223                 cout << a[i] << "->";
224             }
225             else
226             {
227                 cout << a[i];
228             }
229         }
230     }
231 }
232 template <typename DataType>
233 char BiTree<DataType>::searchParent(char a, BiNode<DataType>* bt)
234 {
235     BiNode<DataType>* Q[100], * q = nullptr;
236     int front = -1, rear = -1;
237     if (bt == nullptr) return '#';//二叉树为空
238     Q[++rear] = bt;
239     while (front != rear)
240     {
241         q = Q[++front];
242         if (q->lchild != nullptr)
243         {
244             if (q->lchild->data == a)
245                 return q->data;
246             Q[++rear] = q->lchild;
247         }
248         if (q->rchild != nullptr)
249         {
250             if (q->rchild->data == a)
251                 return q->data;
252             Q[++rear] = q->rchild;
253         }
254     }
255     return '#';
256 }
257 template <typename DataType>
258 int BiTree<DataType>::max(int a, int b)
259 {
260     if (a > b)
261         return a;
262     return b;
263 }
264 template <typename DataType>
265 int BiTree<DataType>::Depth(BiNode<DataType>* bt)
266 {
267     if (bt == nullptr) return 0;
268     return (1+ max(Depth(bt->lchild), Depth(bt->rchild)));
269 }
270 template <typename DataType>
271 void BiTree<DataType>::showLeaf(BiNode<DataType>* bt)
272 {
273     if (bt == nullptr) return;
274     else
275     {
276         if (bt->lchild == nullptr && bt->rchild == nullptr)
277             cout << bt->data << " ";
278         else
279         {
280             showLeaf(bt->lchild);
281             showLeaf(bt->rchild);
282         }
283     }
284 }
285 template <typename DataType>
286 int BiTree<DataType>::getAll(BiNode<DataType>* bt)
287 {
288     int count = 0;
289     if (bt == nullptr) return count;
290     else
291     {
292         count++;
293         count += getAll(bt->lchild);
294         count += getAll(bt->rchild);
295     }
296     return count;
297 }
298 template <typename DataType>
299 int BiTree<DataType>::getCount(BiNode<DataType>* bt)
300 {
301     int count = 0;
302     if (bt == nullptr) return 0;
303     if (bt->lchild == nullptr && bt->rchild == nullptr)
304     {
305         count++;
306     }
307     else
308     {
309         if (bt->lchild != nullptr)
310         {
311             count += getCount(bt->lchild);
312         }
313         if (bt->rchild != nullptr)
314         {
315             count += getCount(bt->rchild);
316         }
317     }
318     return count;
319 }
320 template <typename DataType>
321 void BiTree<DataType>::PreOrder(BiNode<DataType>* bt)//前序遍历
322 {
323     if (bt == nullptr) return;
324     else
325     {
326         cout << bt->data << " ";
327         if (bt->lchild != nullptr)
328             PreOrder(bt->lchild);
329         if (bt->rchild != nullptr)
330             PreOrder(bt->rchild);
331     }
332 }
333 template <typename DataType>
334 void BiTree<DataType>::InOrder(BiNode<DataType>* bt)//中序遍历
335 {
336     if (bt == nullptr) return;
337     else
338     {
339         PreOrder(bt->lchild);
340         cout << bt->data << " ";
341         PreOrder(bt->rchild);
342     }
343 }
344 template <typename DataType>
345 void BiTree<DataType>::PostOrder(BiNode<DataType>* bt)//后序遍历
346 {
347     if (bt == nullptr) return;
348     else
349     {
350         PreOrder(bt->lchild);
351         PreOrder(bt->rchild);
352         cout << bt->data << " ";
353     }
354 }
355 template<typename DataType>
356 void BiTree<DataType>::LevelOrder()//层序遍历
357 {
358     BiNode<DataType>* Q[100], * q = nullptr;
359     int front = -1, rear = -1;
360     if (root == nullptr) return;//二叉树为空
361     Q[++rear] = root;
362     while (front != rear)
363     {
364         q = Q[++front];
365         cout << q->data << " ";
366         if (q->lchild != nullptr) Q[++rear] = q->lchild;
367         if (q->rchild != nullptr) Q[++rear] = q->rchild;
368     }
369 }
370 template <typename DataType>
371 BiNode<DataType>* BiTree<DataType>::Creat()//建立二叉树
372 {
373     BiNode<DataType>* bt;
374     char ch;
375     cin >> ch;
376     if (ch == '#') bt = nullptr;
377     else
378     {
379         bt = new BiNode<DataType>; bt->data = ch;
380         bt->lchild = Creat();
381         bt->rchild = Creat();
382     }
383     return bt;
384 }
385 template<typename DataType>
386 void BiTree<DataType>::Release(BiNode<DataType>* bt)//销毁二叉树
387 {
388     if (bt == nullptr) return;
389     else
390     {
391         Release(bt->lchild);
392         Release(bt->rchild);
393         delete bt;
394     }
395 }

 

欢迎路过的大佬指出可以改进之处,小子感激不尽。

posted @ 2020-12-03 11:18  喃南瓜  阅读(158)  评论(0)    收藏  举报