桂林理工大学软件综合实习二叉树的建立与遍历何天从.docx
《桂林理工大学软件综合实习二叉树的建立与遍历何天从.docx》由会员分享,可在线阅读,更多相关《桂林理工大学软件综合实习二叉树的建立与遍历何天从.docx(25页珍藏版)》请在冰豆网上搜索。
![桂林理工大学软件综合实习二叉树的建立与遍历何天从.docx](https://file1.bdocx.com/fileroot1/2023-7/11/c8eddc36-f452-4e71-8cb9-43766c02e802/c8eddc36-f452-4e71-8cb9-43766c02e8021.gif)
桂林理工大学软件综合实习二叉树的建立与遍历何天从
软件综合实习报告
课题名称二叉树的建立与遍历
姓名何天从
学号3110757101
班级网络11-1班
院(系)信息科学与工程学院
指导教师陈基漓王宇农坚
起止日期2013.6.3~2013.6.21
二叉树的建立与遍历
1、需求分析
1.1二叉树的建立与遍历的功能
1.1.1从键盘接受输入(以字符形式按先序遍历输入),以二叉链表作为存储结构,建立二叉树;【用#表示空子树】
1.1.2对其进行遍历(先序、中序、后序),输出遍历结果;
1.1.3采用非递归算法实现二叉树遍历;【选作内容,已实现】
1.1.4用函数system("cls"),清空屏幕。
【自加内容,已实现】
1.2设计思路
1.2.1先定义每个二叉树的节点的属性,由于是链表式的二叉树,所以每个节点都有一个数据域,以及一个指向左孩子的左指针,指向右孩子的右指针。
1.2.2以字符形式按先序遍历输入二叉树,并存储二叉树;
1.2.3对其进行各种排序,可以用递归排序和非递归排序;
1.3设计思路分析
二叉树是通过建立一个链式存储结构,达到能够实现前序遍历,中序遍历,后序遍历。
以及能够从输入的数据中得知二叉树的叶子节点的个数。
所以,每个节点都有一个数据域,以及一个指向左孩子的左指针,指向右孩子的右指针。
【实现存储】
为了实现存储,定义链表,并以先序遍历方式输入二叉树。
【实现前序遍历】
若二叉树非空,则依次执行如下操作:
访问根结点、遍历左子树、遍历右子树。
【实现中序遍历】
若二叉树非空,则依次执行如下操作:
遍历左子树、访问根结点、遍历右子树。
【实现后序遍历】
若二叉树非空,则依次执行如下操作:
遍历左子树、遍历右子树、访问根结点。
2、概要设计
2.1为了实现上述程序功能,需要定义链表的抽象数据类型:
typedefstructBiTNode
{chardata;//数据
structBiTNode*lchild,*rchild;//左、右子树指针
}BiTNode,*BiTree;
2.2本程序包含8个函数:
1、intmain()【主函数】
2、voidCreatBiTree(BiTree&T)【建立二叉树函数】
3、voidPreOrderTraverse(BiTree&T)【前序遍历递归】
4、voidInorderTraverse(BiTree&T)【中序遍历递归】
5、voidPostTravel(BiTree&T)【后序遍历递归】
6、voidpreOrderTraverse(BiTreeT)【前序遍历非递归】
7、voidinorderTraverse(BiTreeT)【中序遍历非递归】
8、voidpostorder(BiTreeT)【后序遍历非递归】
2.3各函数间关系如下(虚线表示函数之间调用):
3、详细设计
实现代码:
#include
#include
#include
#include
//╞╪╪╪╪╪╪╪╪【定义链表的数据结构】╪╪╪╪╪╪╪╪╪╪╪╪╪╪╡
typedefstructBiTNode
{chardata;
structBiTNode*lchild,*rchild;
}BiTNode,*BiTree;
//╞╪╪╪╪╪╪╪╪╪【建立一棵二叉树】╪╪╪╪╪╪╪╪╪╪╪╪╪╪╡
voidCreatBiTree(BiTree&T)
{charch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{T=(BiTree)malloc(sizeof(BiTNode));
if(!
T)
exit(0);
T->data=ch;
CreatBiTree(T->lchild);
CreatBiTree(T->rchild);
}
}
//╞╪╪╪╪╪╪╪╪╪【前序遍历递归】╪╪╪╪╪╪╪╪╪╪╪╪╪╪╡
voidPreOrderTraverse(BiTree&T)
{
if(T)
{cout<data<<"";
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);}
}
//╞╪╪╪╪╪╪╪╪╪【中序遍历递归】╪╪╪╪╪╪╪╪╪╪╪╪╪╪╡
voidInorderTraverse(BiTree&T)
{
if(T)
{InorderTraverse(T->lchild);
cout<data<<"";
InorderTraverse(T->rchild);
}}
//╞╪╪╪╪╪╪╪╪╪【后序遍历递归】╪╪╪╪╪╪╪╪╪╪╪╪╪╪╡
voidPostTravel(BiTree&T)
{
if(T)
{
PostTravel(T->lchild);
PostTravel(T->rchild);
cout<data<<"";
}
}
//╞╪╪╪╪╪╪╪╪╪【前序遍历非递归】╪╪╪╪╪╪╪╪╪╪╪╪╪╪╡
voidpreOrderTraverse(BiTreeT)
{BiTreeS[20];
inttop=-1;
do
{while(T!
=NULL)
{cout<data<<"";
top++;
S[top]=T;
T=T->lchild;
}
if(top>-1)
{T=S[top];
top--;
T=T->rchild;
}
}while((T!
=NULL)||(top>-1));
}
//╞╪╪╪╪╪╪╪╪╪【中序遍历非递归】╪╪╪╪╪╪╪╪╪╪╪╪╪╪╡
voidinorderTraverse(BiTreeT)
{BiTrees[20];
inti=-1;
while(T||i>-1)
{if(T)
{i++;
s[i]=T;
T=T->lchild;
}
else
{
T=s[i];
cout<data<<"";
i--;
T=T->rchild;}}}
//╞╪╪╪╪╪╪╪╪╪【后序遍历非递归】╪╪╪╪╪╪╪╪╪╪╪╪╪╪╡
voidpostorder(BiTreeT)
{BiTrees1[20];
ints2[20],top=0;
do{
while(T!
=NULL)
{s1[top]=T;
s2[top++]=0;
T=T->lchild;
}
while(top&&s2[top-1]==1)
{top--;
T=s1[top];
cout<data<<"";
}
if(top>0)
{
s2[top-1]=1;
T=s1[top-1]->rchild;
}
}while(top>0);
}
//╞╪╪╪╪╪╪╪╪╪【主函数】╪╪╪╪╪╪╪╪╪╪╪╪╪╪╡
voidmain()
{printf("◢■■◣◢■■◣◢■ ◢■■◣◢■■◣◢■■◣◢■\n");
printf(" ■■ ■ ■ ■■ ■ ■\n");
printf("◢■■◤■ ■ ■ ■■■■年■■■■月◢■■◤ ■号\n");
printf("■ ■ ■ ■ ■■■■ ■\n");
printf("◥■■■◥■■◤◥■■■◤◥■■◤◥■■◤◥■■■◥■■■◤\n");
printf("\n");
printf("━━━━━━━━━【作者】━━━━━━━━━━━━━━\n");
printf("┃┃\n");
printf("┃●何天从┃\n");
printf("┃●网络工程专业11-1班┃\n");
printf("┃●学号:
3110757101┃\n");
printf("┃●信息科学与工程学院┃\n");
printf("┃●桂林理工大学┃\n");
printf("┃┃\n");
printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");printf("\n");printf("\n");
printf("┣━━━━━━━━━【二叉树遍历】━━━━━━━━━━┫\n");
printf("┃┃\n");
printf("┃⑴〖输入一棵二叉树(用#表示空):
〗┃\n");
printf("┃⑵〖输出先序递归遍历结果〗┃\n");
printf("┃⑶〖输出中序递归遍历结果〗┃\n");
printf("┃⑷〖输出后序递归遍历结果〗┃\n");
printf("┃⑸〖输出先序非递归遍历结果〗┃\n");
printf("┃⑹〖输出中序非递归遍历结果〗┃\n");
printf("┃⑺〖输出后序非递归遍历结果〗┃\n");
printf("┃⑻〖清空屏幕〗┃\n");
printf("┃(O)〖结束遍历〗┃\n");
printf("┃┃\n");
printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");printf("\n");
BiTreeT;
inte;
while(e!
=0)
{
cout<";
cin>>e;
cout<if(e==1)
{
cout<<"【请输入】一棵二叉树(用#表示空):
";
CreatBiTree(T);
cout<}
if(e==2)
{cout<<"【输出】先序递归遍历结果:
";
PreOrderTraverse(T);
cout<}
if(e==3)
{cout<<"【输出】中序递归遍历结果:
";
InorderTraverse(T);
cout<}
if(e==4)
{cout<<"【输出】后序递归遍历结果:
";
PostTravel(T);
cout<}
if(e==5)
{cout<<"【输出】先序非递归遍历结果:
";
preOrderTraverse(T);
cout<}
if(e==6)
{cout<<"【输出】中序非递归遍历结果:
";
inorderTraverse(T);
}
if(e==7)
{cout<<"【输出】后序非递归遍历结果:
";
postorder(T);
cout<}
if(e==8)
{system("cls");//清屏函数
printf("┣━━━━━━━━━【二叉树遍历】━━━━━━━━━━┫\n");
printf("┃┃\n");
printf("┃⑴〖输入一棵二叉树(用#表示空):
〗┃\n");
printf("┃⑵〖输出先序递归遍历结果〗┃\n");
printf("┃⑶〖输出中序递归遍历结果〗┃\n");
printf("┃⑷〖输出后序递归遍历结果〗┃\n");
printf("┃⑸〖输出先序非递归遍历结果〗┃\n");
printf("┃⑹〖输出中序非递归遍历结果〗┃\n");
printf("┃⑺〖输出后序非递归遍历结果〗┃\n");
printf("┃⑻〖清空屏幕〗┃\n");
printf("┃(O)〖结束遍历〗┃\n");
printf("┃┃\n");
printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
printf("\n");
}
if(e>8||e<0)
{
cout<<"【输入有误】请从新输入!
!
";
cout<}
}
}
4、调试分析
通过二叉树的建立与遍历的编程练习,通过以前的学习以及查看相关资料,对指针、链表等的深入了解,本次实验中,二叉树的先序、中序和后序遍历都采用了递归调用和非递归调用。
在编写过程中,遇到的问题不是技术问题,而是二叉树遍历的本质问题,就是如何遍历。
二叉树中的递归,最本质的东西是:
每个结点都是平等的,即根结点所代表的二叉树,与以任何结点为根的子树具有相同的结构性质,因此,对根结点所代表的二叉树的处理方法与以任何其他结点为根的子树的处理方法一样,且子树的规模比原树还小,从而可以进行递归定义,求解和处理。
5、使用说明
5.1.程序名为二叉树的建立与遍历.exe,运行环境为DOS。
5.2.程序执行后显示主菜单:
5.2.1主菜单功能选择:
选择⑴〖输入一棵二叉树(用#表示空):
〗
选择⑵〖输出先序递归遍历结果〗
选择⑶〖输出中序递归遍历结果〗
选择⑷〖输出后序递归遍历结果〗
选择⑸〖输出先序非递归遍历结果〗
选择⑹〖输出中序非递归遍历结果〗
选择⑺〖输出后序非递归遍历结果〗
选择⑻〖清空屏幕〗选择(O)〖结束遍历〗
6、测试结果
⑴〖输入一棵二叉树(用#表示空):
〗
⑵〖输出先序递归遍历结果〗
⑶〖输出中序递归遍历结果〗
⑷〖输出后序递归遍历结果〗
⑸〖输出先序非递归遍历结果〗
⑹〖输出中序非递归遍历结果〗
⑺〖输出后序非递归遍历结果〗
⑻〖清空屏幕〗
清空屏幕,并返回主菜单。
(O)〖结束遍历〗
7、实习心得
通过二叉树的建立与遍历的编程,认真回顾和重新思考数据结构的使用,比如对指针、链表等的深入了解,让我感受到了数据结构及其算法的重要。
虽然二叉树是数据结构的的基本内容,但是在编程过程中,仍免不了各种错误的出现。
我用自己有毅力和耐心,经过不断的努力,最终完成了递归遍历和非递归遍历。
在实习这三周里,我遇到了很多的困难,当自己认真思考后还在纠结时,我会跟同学们一起交流,或者向老师请教。
在这里衷心地感谢老师和同学们的帮助!
2013年6月27日星期四
由于上面的原代码编排过,可以编译时出错,下面附没有编排的:
#include
#include
#include
#include
typedefstructBiTNode
{
chardata;
structBiTNode*lchild,*rchild;
intLTag,RTag,flag;
}BiTNode,*BiTree;
voidCreatBiTree(BiTree&T)//建立一棵二叉树
{
charch;
cin>>ch;
if(ch=='#')
T=NULL;
else
{
T=(BiTree)malloc(sizeof(BiTNode));
if(!
T)
exit(0);
T->data=ch;
CreatBiTree(T->lchild);
CreatBiTree(T->rchild);
}
}
voidPreOrderTraverse(BiTree&T)
{//前序遍历递归
if(T)
{
cout<data<<"";
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
voidInorderTraverse(BiTree&T)
{//中序遍历递归
if(T)
{
InorderTraverse(T->lchild);
cout<data<<"";
InorderTraverse(T->rchild);
}
}
voidPostTravel(BiTree&T)
{//后序遍历递归
if(T)
{
PostTravel(T->lchild);
PostTravel(T->rchild);
cout<data<<"";
}
}
voidpreOrderTraverse(BiTreeT)
{//前序遍历非递归
BiTreeS[20];
inttop=-1;
do
{
while(T!
=NULL)
{
cout<data<<"";
top++;
S[top]=T;
T=T->lchild;
}
if(top>-1)
{
T=S[top];
top--;
T=T->rchild;
}
}while((T!
=NULL)||(top>-1));
}
intinorderTraverse(BiTreeT)
{//中序遍历非递归
BiTrees[20];
inti=-1;
while(T||i>-1)
{
if(T)
{
i++;
s[i]=T;
T=T->lchild;
}
else
{
T=s[i];
cout<data<<"";
i--;
T=T->rchild;
}
}
return0;
}
voidpostorder(BiTreeT)
{//后序遍历非递归
BiTrees1[20];
ints2[20],top=0;
do{
while(T!
=NULL)
{
s1[top]=T;
s2[top++]=0;
T=T->lchild;
}
while(top&&s2[top-1]==1)
{
top--;
T=s1[top];
cout<data<<"";
}
if(top>0)
{
s2[top-1]=1;
T=s1[top-1]->rchild;
}
}while(top>0);
}
voidmain()//主函数
{
printf("◢■■◣◢■■◣◢■ ◢■■◣◢■■◣◢■■◣◢■\n");
printf(" ■■ ■ ■ ■■ ■ ■\n");
printf("◢■■◤■ ■ ■ ■■■■年■■■■月◢■■◤ ■号\n");
printf("■ ■ ■ ■ ■■■■ ■\n");
printf("◥■■■◥■■◤◥■■■◤◥■■◤◥■■◤◥■■■◥■■■◤\n");
printf("\n");
printf("━━━━━━━━━【作者】━━━━━━━━━━━━━━\n");
printf("┃┃\n");
printf("┃●何天从┃\n");
printf("┃●网络工程专业11-1班┃\n");
printf("┃●学号:
3110757101┃\n");
printf("┃●信息科学与工程学院┃\n");
printf("┃●桂林理工大学┃\n");
printf("┃┃\n");
printf("━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
printf("\n");
printf("\n");
printf("┣━━━━━━━━━【二叉树遍历】━━━━━━━━━━┫\n");
printf("┃┃\n");
printf("┃⑴〖输入一棵二叉树(用#表示空):
〗┃\n");
printf("┃⑵〖输出先序递归遍历结果〗┃\n");
printf("┃⑶〖输出中序递归遍历结果〗┃\n");
printf("┃⑷〖输出后序递归遍历结果〗┃\n");
printf("┃⑸〖输出先序非递归遍历结果〗┃\n");
printf("┃⑹〖输出中序非递归遍历结果〗┃\n");
printf("┃⑺〖输出后序非递归遍历结果〗┃\n");
printf("┃⑻〖清空屏幕〗┃\n");
printf("┃(O)〖结束遍历〗┃\n");
printf("┃┃\n");
printf("┣━━━━━━━━━━━━━━━━━━━━━━━━━━┫\n");
printf("\n");
BiTreeT;
inte;
while(e!
=0)
{
cout<";
cin>>e;
cout<if(e==1)
{
cout<<"【请输入】输入一棵二叉树(用#表示空):
";
CreatBiTree(T);
cout<}
if(e==2)
{
cout<<"【输出】先序递归遍历结果:
";
PreOrderTraverse(T);
cout<}
if(e==3)
{
cout<<"【输出】中序递归遍历结果:
";
InorderTraverse(T);
cout<}
if(e==4)
{
cout<<"【输出】后序递归遍历结果:
";
PostTravel(T);
cout<}
if(e==5)
{
cout<<"【输出】先序非递归遍历结果:
";
preOrderTraverse(T);
cout<}
if(e==6)
{
cout<<"【输出】中序非递归遍历结果:
";
inor