【数据结构】C++二叉树的实现(二叉链表),包括初始化,前序、中序、后序、层次遍历,计算节点数、叶子数、高度、宽度,二叉树的复制和销毁

 *********************************************************************************************************

本文作者科大MF22某班Noah懒羊羊同学,为大家提供一个作业思路,请勿直接copy!!!一起进步学习~

**********************************************************************************************************

目录

1.问题的描述

1.1基本功能

1.2健壮性

1.3 规范性

2.算法的描述

2.1数据结构的描述

2.2程序结构的描述

3.调试分析

4.算法的时空分析

5.测试结果及分析

6.实验体会和收获

代码

Noah_BiTree.h

 main.cpp


1.问题的描述

1.1基本功能

1、创建二叉树(10’)

可以使用先序遍历输入,无节点的可以使用#表示。

例如下图可以输入6423####51##7##。这里前面2个#表示节点3左右孩子节点都为空,第3个#表示节点2右孩子为空,第4个#表示节点4右孩子为空,1和7后面的2个#分别代表节点1和7的左右孩子节点都为空。

也可以自己选择其他方式输入,但要在readme文件和实验报告说清楚。

2、遍历二叉树(先序、中序、后序、层序遍历)(20’)

前序遍历:6423517

中序遍历:3246157

后序遍历:3241756

层序遍历:6452173

3、二叉树的计算(二叉树的结点数、叶子数、高度、宽度等)(20’)

结点数:7

叶子数:3

高度:4

宽度:3

4、 二叉树的处理(复制、销毁)(20’)

复制要创建一个新的二叉树,对于原二叉树和复制的二叉树之间销毁操作不能互相影响。

1.2健壮性

  1. 对于创建的二叉树为空的情况,要能程序要能正常运行并识别。(5分)
  2. 对于空树,其他功能要可以识别、输出相应信息,并且程序不能异常终止。(5分)

1.3 规范性

  1. 代码注释
  2. 程序模块化
  3. 人机交互友好

2.算法的描述

2.1数据结构的描述

程序中应用到的主要数据结构是二叉树(二叉链表)。

主要变量说明:

变量

类型

说明

Node、BiTNode

结构体

二叉树结点的结构体

*BiTree

二叉树结点指针

二叉树结点的指针

data

可变(由宏定义TElemType确定,示例中为char)

二叉树结点中的数据域

*lchild

二叉树结点指针

结点的左孩子

*rchild

二叉树结点指针

结点的右孩子

TElemType

宏定义

二叉树节点数据域的类型

2.2程序结构的描述

        程序主要包含Noah_BiTree.h头文件和main.cpp主文件,其中Noah_BiTree.h是二叉链表数据结构的实现代码头文件,N,main.cpp中主要实现菜单和功能界面的交互以及头文件中函数的调用。其具体结构如下图所示。

3.调试分析

调试功能一:Create a binary tree and show the tree structure

创建二叉树并显示树的结构

测试数据选择:

  1. 6423####51##7##
  2. 124##5##36##7##
  3. #
  4. 1234######

问题及解决方法:

调试功能二:Create a binary tree and show show the preoeder, inorder, postorder and levelorder

创建一个二叉树,显示前序、中序后序和层次遍历。

测试数据选择:

  1. 6423####51##7##
  2. 124##5##36##7##
  3. 1234######

问题及解决方法:

调试功能三:Create a binary tree and calculate the number of nodes, leaves, height and width

创建一个二叉树,计算节点的数量,叶,高度和宽度

测试数据选择:

  1. 6423####51##7##
  2. 124##5##36##7##
  3. 1234######

问题及解决方法:

调试功能四:Create a binary tree, copy it, destory the original one and show the new tree

创建一个二叉树,复制它,销毁原来的树,并显示新的树

测试数据选择:

  1. 6423####51##7##
  2. 124##5##36##7##
  3. 1234######

问题及解决方法:

4.算法的时空分析

(1) CreateBiTree_withhint(BiTree &T)

时间复杂度:O(n)

空间复杂度:O(n)

(2) preorder(BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

(3) inorder(BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

(4) postorder(BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

(5) levelorder(BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

(6) NumofNode (BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

(7) BiHight (BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

(7) Numofleaves (BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

(7) BiWidth (BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

(7) CopyBitree (BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

(7) DestroyBiTree (BiTree T)

时间复杂度:O(n)

空间复杂度:O(n)

5.测试结果及分析

测试功能一:Create a binary tree and show the tree structure

测试用例

结果

分析

6423####51##7##

124##5##36##7##

#

1234######

调试功能二:Create a binary tree and show show the preoeder, inorder, postorder and levelorder

测试用例

结果

分析

6423####51##7##

124##5##36##7##

1234######

测试功能三:Create a binary tree and calculate the number of nodes, leaves, height and width

测试用例

结果

分析

6423####51##7##

124##5##36##7##

1234######

调试功能四:Create a binary tree, copy it, destory the original one and show the new tree

测试用例

结果

分析

6423####51##7##

124##5##36##7##

1234######

6.实验体会和收获

  1.      掌握二叉树的递归特性
  2.      掌握二叉树的常用存储结构----二叉链表
  3.      掌握二叉树的创建、遍历等基本运算
  4.      了解递归函数的执行过程,学会编写递归程序

代码

Noah_BiTree.h

1.	#ifndef __NOAH_BITREE_H__  
2.	#define __NOAH_BITREE_H__  
3.	#include <stdlib.h>  
4.	#include <iostream>  
5.	#include <cstring>  
6.	#include <queue>  
7.	#include <string>  
8.	#include <iostream>  
9.	using namespace std;  
10.	#define TElemType char  
11.	/* 
12.	1.  对于创建的二叉树为空的情况,要能程序要能正常运行并识别。(5分) 
13.	2.  对于空树,其他功能要可以识别、输出相应信息,并且程序不能异常终止。(5分) 
14.	*/  
15.	typedef struct Node  
16.	{  
17.	    TElemType data;  
18.	    struct Node *lchild,*rchild;//左右孩子指针  
19.	}BiTNode,*BiTree;  
20.	  
21.	void CreateBiTree_Preorder(BiTree &T){  
22.	    //使用先序遍历的输入创建一个二叉树,例如6423####51##7##  
23.	    char x;  
24.	    cin>>x;  
25.	    if(x==' '||x=='#'){  
26.	        T = NULL;  
27.	    }  
28.	    else {  
29.	        T = (BiTree)malloc(sizeof(BiTNode));  
30.	        if(x !='#')  
31.	            T->data = (TElemType)x;  
32.	        CreateBiTree_Preorder(T->lchild);  
33.	        CreateBiTree_Preorder(T->rchild);  
34.	    }  
35.	}  
36.	  
37.	void CreateBiTree_withhint(BiTree &T){  
38.	    //向屏幕输出初始化二叉树的提示信息,调用CreateBiTree_Preorder()  
39.	    cout<<"Please input a preorder sequence of a binary tree(example:6423####51##7##):"<<endl;  
40.	    CreateBiTree_Preorder(T);  
41.	    if(T==NULL) cout<<"Input is an empty BiTree."<<endl;  
42.	}  
43.	  
44.	int isBiTreeEmpty(BiTree T){  
45.	    //判断二叉树是否为空,为空返回1,不为空返回0  
46.	    if((T->data == NULL && T->lchild && T->rchild)||T==NULL)  
47.	        return 1;  
48.	    else  
49.	        return 0;  
50.	}  
51.	  
52.	void preorder(BiTree T){  
53.	    //使用先序遍历输出二叉树  
54.	    if(T){  
55.	        cout<<T->data;  
56.	        preorder(T->lchild);  
57.	        preorder(T->rchild);  
58.	    }  
59.	    else  
60.	        return;  
61.	        //cout<<"Empty BiTree."<<endl;  
62.	}  
63.	  
64.	void inorder(BiTree T){  
65.	    //使用中序遍历输出二叉树  
66.	    if(T){  
67.	        inorder(T->lchild);  
68.	        cout<<T->data;  
69.	        inorder(T->rchild);  
70.	    }  
71.	}  
72.	  
73.	void postorder(BiTree T){  
74.	    //使用后序遍历输出二叉树  
75.	    if(T){  
76.	        postorder(T->lchild);  
77.	        postorder(T->rchild);  
78.	        cout<<T->data;  
79.	    }  
80.	}  
81.	  
82.	void leverorder(BiTree T){  
83.	    //使用层次遍历输出二叉树  
84.	    if(T){  
85.	        queue<BiTree> q;  
86.	        q.push(T);  
87.	        while(!q.empty()){//当队列非空时,还有没有遍历的parent结点  
88.	            BiTree temp = q.front();  
89.	            q.pop();  
90.	            cout<<temp->data;  
91.	            if(temp->lchild!=NULL) q.push(temp->lchild);  
92.	            if(temp->rchild!=NULL) q.push(temp->rchild);  
93.	        }  
94.	    }  
95.	}  
96.	  
97.	int NumofNode(BiTree T){  
98.	    //返回二叉树节点数  
99.	    if(!T) return 0;  
100.	    else return 1 + NumofNode(T->lchild) + NumofNode(T->rchild);  
101.	}  
102.	  
103.	int Numofleaves(BiTree T){  
104.	    //返回二叉树叶子数  
105.	    int num = 0;  
106.	    if(!T) return 0;  
107.	    else{  
108.	        if(T->lchild!=NULL) num = num + Numofleaves(T->lchild);  
109.	        if(T->rchild!=NULL) num = num + Numofleaves(T->rchild);  
110.	        if(T->lchild==NULL && T->rchild==NULL) return 1;  
111.	    }  
112.	    return num;  
113.	}  
114.	  
115.	int BiHight(BiTree T){  
116.	    //返回二叉树高度  
117.	    if(!T) return 0;  
118.	    else{  
119.	        int lefthight = BiHight(T->lchild);  
120.	        int righthight = BiHight(T->rchild);  
121.	        return (lefthight>=righthight)?lefthight+1:righthight+1;  
122.	    }  
123.	}  
124.	  
125.	int BiWidth(BiTree T){  
126.	    //返回二叉树宽度  
127.	    if (isBiTreeEmpty(T)) {  
128.	        return 0;  
129.	    }  
130.	    queue<BiTree> q;  
131.	    int maxWidth = 1;  
132.	    q.push(T);  
133.	  
134.	    while (1) {  
135.	        int len = q.size();  
136.	        if (!len) {  
137.	            break;  
138.	        }  
139.	        while (len--) {  
140.	  
141.	            BiTree temp = q.front();  
142.	            q.pop();  
143.	            if (temp->lchild) {  
144.	                q.push(temp->lchild);  
145.	            }  
146.	            if (temp->rchild) {  
147.	                q.push(temp->rchild);  
148.	            }  
149.	        }  
150.	        maxWidth = max(maxWidth, (int) q.size());  
151.	    }  
152.	    return maxWidth;  
153.	}  
154.	  
155.	void CopyBitree(BiTree source,BiTree &target){  
156.	    //将source中的二叉树复制给target,原二叉树和复制的二叉树之间销毁操作不能互相影响  
157.	    if(!source){  
158.	        target = NULL;  
159.	        return;  
160.	    }  
161.	  
162.	    else{  
163.	        target = (BiTNode *)malloc(sizeof(BiTNode));  
164.	        target->data = (TElemType)source->data;  
165.	        CopyBitree(source->lchild,target->lchild);  
166.	        CopyBitree(source->rchild,target->rchild);  
167.	    }  
168.	}  
169.	  
170.	  
171.	void DestroyBiTree(BiTree &T){  
172.	    //销毁二叉树并释放内存  
173.	    if(isBiTreeEmpty(T)){  
174.	        cout<<"DestroyBiTree succeed."<<endl;  
175.	        return;  
176.	    }  
177.	    else{  
178.	        if(T->lchild!=NULL) DestroyBiTree(T->lchild);  
179.	        if(T->rchild!=NULL) DestroyBiTree(T->rchild);  
180.	        free(T);  
181.	        T = NULL;  
182.	    }  
183.	}  
184.	  
185.	void DisplayBitree_control(BiTree n, bool left, string const& indent){  
186.	    //DisplayBitree()函数的中间控制函数  
187.	    if (n->rchild)  
188.	    {  
189.	        DisplayBitree_control(n->rchild, false, indent + (left ? "|     " : "      "));  
190.	    }  
191.	    cout << indent;  
192.	    cout << (left ? '\\' : '/');  
193.	    cout << "-----";  
194.	    cout << n->data << endl;  
195.	    if (n->lchild)  
196.	    {  
197.	        DisplayBitree_control(n->lchild, true, indent + (left ? "      " : "|     "));  
198.	    }  
199.	}  
200.	void DisplayBitree(BiTree root){  
201.	    //以树形结构形式输出二叉树  
202.	    if(!root){  
203.	        cout<<"An empty tree."<<endl;  
204.	        return;  
205.	    }  
206.	    if (root->rchild)  
207.	    {  
208.	        DisplayBitree_control(root->rchild, false, "");  
209.	    }  
210.	    cout << root->data << endl;  
211.	    if (root->lchild)  
212.	    {  
213.	        DisplayBitree_control(root->lchild, true, "");  
214.	    }  
215.	}  
216.	#endif  

 main.cpp

1.	#include <stdio.h>  
2.	#include <string.h>  
3.	#include <stdlib.h>  
4.	#include <iostream>  
5.	using namespace std;  
6.	#include "Noah_BiTree.h"  
7.	void Menue_gui();  
8.	void func1();  
9.	void func2();  
10.	void func3();  
11.	void func4();  
12.	  
13.	int main()  
14.	{  
15.	    while(1){  
16.	        Menue_gui();  
17.	        int func;  
18.	        scanf("%d",&func);  
19.	        switch(func){  
20.	            case 0:  
21.	                exit(0);  
22.	            case 1:  
23.	                func1();break;  
24.	            case 2:  
25.	                func2();break;  
26.	            case 3:  
27.	                func3();break;  
28.	            case 4:  
29.	                func4();break;  
30.	            default:  
31.	                printf("Input error! Please try again!");  
32.	        }  
33.	        printf("\n");  
34.	        system("pause");  
35.	    }  
36.	    return 0;  
37.	}  
38.	  
39.	//主界面  
40.	void Menue_gui(){  
41.	    system("cls");  
42.	    printf("**********************************Binary Tree calcuator**************************************\n");  
43.	    printf("*********************************************************************************************\n");  
44.	    printf("Menue:\n");  
45.	    printf("\nExit this program------------------------------------------------------------------0.\n");  
46.	    printf("\nCreate a binary tree and show the tree structure-----------------------------------1.\n");  
47.	    printf("\nCreate a binary tree and show show the preoeder, inorder, postorder and levelorder-2.\n");  
48.	    printf("\nCreate a binary tree and calculate the number of nodes, leaves, height and width---3.\n");  
49.	    printf("\nCreate a binary tree, copy it, destory the original one and show the new tree------4.\n");  
50.	    printf("\n**********************************************************************************************\n");  
51.	    printf("Choose the function you want to use(input number):\n");  
52.	}  
53.	  
54.	void func1(){  
55.	    system("cls");  
56.	    printf("-----ENTER FUNCTION : Create a binary tree and show the tree structure--1.-----\n");  
57.	    BiTree T1;  
58.	    CreateBiTree_withhint(T1);  
59.	    DisplayBitree(T1);  
60.	}  
61.	void func2(){  
62.	    system("cls");  
63.	    printf("-----ENTER FUNCTION : Create a binary tree and show show the preoeder, inorder, postorder and levelorder--2.-----\n");  
64.	    BiTree T1;  
65.	    CreateBiTree_withhint(T1);  
66.	    cout<<endl<<"The tree form of the Binary Tree is:"<<endl;  
67.	    DisplayBitree(T1);  
68.	    cout<<endl<<"The preorder of the Binary Tree is:"<<endl;  
69.	    preorder(T1);  
70.	    cout<<endl<<"The inorder of the Binary Tree is:"<<endl;  
71.	    inorder(T1);  
72.	    cout<<endl<<"The postorder of the Binary Tree is:"<<endl;  
73.	    postorder(T1);  
74.	    cout<<endl<<"The levelorder of the Binary Tree is:"<<endl;  
75.	    leverorder(T1);  
76.	}  
77.	void func3(){  
78.	    system("cls");  
79.	    printf("-----ENTER FUNCTION : Create a binary tree and calculate the number of nodes, leaves, height and width--3.-----\n");  
80.	    BiTree T1;  
81.	    CreateBiTree_withhint(T1);  
82.	    cout<<endl<<"The tree form of the Binary Tree is:"<<endl;  
83.	    DisplayBitree(T1);  
84.	    cout<<endl<<"The number of nodes is:"<<NumofNode(T1)<<endl;  
85.	    cout<<endl<<"The number of leaves is:"<<Numofleaves(T1)<<endl;  
86.	    cout<<endl<<"The height is:"<<BiHight(T1)<<endl;  
87.	    cout<<endl<<"The width is:"<<BiWidth(T1)<<endl;  
88.	}  
89.	void func4(){  
90.	    system("cls");  
91.	    printf("-----ENTER FUNCTION : Create a binary tree, copy it, destory the original one and show the new tree--4.-----\n");  
92.	    BiTree T1;  
93.	    CreateBiTree_withhint(T1);  
94.	    cout<<endl<<"The tree form of the [ORIGINAL] Binary Tree is:"<<endl;  
95.	    DisplayBitree(T1);  
96.	    BiTree T2;  
97.	    CopyBitree(T1,T2);//复制T1到T2  
98.	    DestroyBiTree(T1);//销毁T1  
99.	    cout<<endl<<"After destroy, the tree form of the [ORIGINAL] Binary Tree is:"<<endl;  
100.	    DisplayBitree(T1);  
101.	    cout<<endl<<"The tree form of the [NEW] Binary Tree is:"<<endl;  
102.	    DisplayBitree(T2);  
103.	}  

猜你喜欢

转载自blog.csdn.net/standingflower/article/details/128126394