数据结构二叉树实验报告.docx
《数据结构二叉树实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构二叉树实验报告.docx(21页珍藏版)》请在冰豆网上搜索。
数据结构二叉树实验报告
二叉树两种存储结构的应用
1、实验题目
实验名称:
二叉树两种存储结构的应用
2、实验目的和要求
1.掌握二叉树的遍历思想及二叉树的存储实现。
2.掌握二叉树的基本操作:
建立二叉树、二叉树的遍历。
3.选择一种形式完成二叉树的显示。
4.掌握二叉树的常见算法的程序实现。
5.实验报告中要写出测试数据、错误分析以及收获。
三、实验内容
二叉树的建立及相关算法的实现
完成的功能包括如下几点:
①编程实现建立一棵二叉树,然后对其进行先序、中序和后序遍历。
②显示二叉树。
③求二叉树的高度及二叉树的叶子个数等等。
④在主函数中设计一个简单的菜单,分别调试上述算法。
四、实验步骤
1、分析讨论实验内容及要求,分配任务;
2、整理实验程序,使之成为完整结合;
3、编译、组建、调试运行程序,得到符合要求的程序及结果。
刘燕楠:
二叉树的建立
王旭峰:
二叉树的递归遍历
夏南南:
二叉树的叶子结点个数求解
许雪峰:
二叉树的树高求解
康凯:
二叉树的显示输出及顺序栈的操作
岳晓芳:
二叉树的非递归遍历以及程序的调试
5、实验程序代码
#include
#include
#include
#include
#include
constintN=100;
intm=0;
typedefstructNode
{
chardata;
intmark;//标注从左还是右回来的
intcount;//标记是否读过
structNode*Lchild;
structNode*Rchild;
}BiTNode,*BiTree;
//顺序栈的操作
typedefstruct{
BiTNodedata[N];
inttop;
}sqstack;
voidpush(sqstack&s,BiTNodee)//入栈
{
if(s.top==N-1)
printf("栈满\n");//判栈满
else
{
s.top++;
s.data[s.top]=e;
}
}
voidpop(sqstack&s)//出栈
{
if(s.top==-1)
printf("栈空!
");//判栈空
else
s.top--;
}
//二叉树的操作
voidCreate(BiTree&T)//二叉树的建立
{
charch;
getchar();
ch=getchar();
if(ch=='#')
T=NULL;
else
{
T=(BiTNode*)malloc(sizeof(BiTNode));
if(T==NULL)
printf("error!
");
T->data=ch;
printf("请输入%c结点的左子树:
",T->data);
Create(T->Lchild);
printf("请输入%c结点的右子树:
",T->data);
Create(T->Rchild);
}
}
voidpreorder(BiTreeT)//先序遍历
{
if(T==NULL)return;
if(T!
=NULL)
{
printf("%c",T->data);
preorder(T->Lchild);
preorder(T->Rchild);
}
}
voidpostorder(BiTreeT)//后序遍历
{
if(T==NULL)return;
if(T!
=NULL)
{
postorder(T->Lchild);
postorder(T->Rchild);
printf("%c",T->data);
}
}
voidinorder(BiTreeT)//中序遍历
{
if(T==NULL)return;
if(T!
=NULL)
{
inorder(T->Lchild);
printf("%c",T->data);
inorder(T->Rchild);
}
}
voidBiTreeleaf(BiTreeT)//求二叉树的叶子结点
{
if(T==NULL)return;
if(T!
=NULL)
{
if(T->Lchild==NULL&&T->Rchild==NULL)
{
m++;
printf("%c",T->data);
}
BiTreeleaf(T->Lchild);
BiTreeleaf(T->Rchild);
}
}
intTreehigh(BiTree&T)//求树高
{
intLH=0,RH=0;
if(T==NULL)return0;
else
{
LH=Treehigh(T->Lchild);
RH=Treehigh(T->Rchild);
if(LH>RH)returnLH+1;
else
returnRH+1;
}
}
//非递归方法先序遍历二叉树
voidstackpreorder(BiTreeT)
{
sqstacks;//栈的初始化
s.top=-1;
if(T!
=NULL)
{
T->mark=0;
T->count=0;//标记未读
push(s,*T);//树不空根结点入栈
}
BiTNode*p;//工作指针
while(s.top!
=-1)//栈不空
{
p=&s.data[s.top];
while(p)
{
if(p->count==0)//未读
{
printf("%c",*p);
p->count=1;//标记已读
}
if(p->mark==2)
return;
else
{
if(p->Lchild!
=NULL&&p->mark==0)//左孩子入栈,直到走到尽头
{
p->mark=1;//表明从左进来的
p->Lchild->mark=0;
push(s,*p->Lchild);
p=&s.data[s.top];
p->count=0;//标记未读
}
else
break;
}
}
if(s.top!
=-1)
{
p=&s.data[s.top];
pop(s);
if(p->Rchild!
=NULL)
{
p->mark=2;//从右进
push(s,*p->Rchild);//右孩子入栈
p=&s.data[s.top];
p->count=0;
}
}
}
}
//非递归方法中序遍历二叉树
voidstackinorder(BiTreeT)
{
sqstacks;//栈的初始化
s.top=-1;
if(T!
=NULL)//树不空根结点入栈
{
T->mark=0;
push(s,*T);
}
BiTNode*p;//工作指针
while(s.top!
=-1)//栈不空
{
while((p=&s.data[s.top])&&p)
{
if(p->Lchild!
=NULL&&p->mark==0)//表明还没走左的
{
//左孩子入栈,直到走到尽头
p->mark=1;//表明从左进来的
p->Lchild->mark=0;
push(s,*p->Lchild);
}
else
{p->mark=1;
break;
}
}
if(s.top!
=-1)
{
p=&s.data[s.top];
if(p->mark==1)//从左子回来,读出
{
printf("%c",*p);
pop(s);
}
p->mark=2;//是从右进入的
if(p->Rchild!
=NULL)
push(s,*p->Rchild);//右孩子入栈
}
}
}
//非递归方法后序遍历二叉树,与中序非常类似,是要判断从右子回来才输出
voidstackpostorder(BiTreeT)
{
sqstacks;//栈的初始化
s.top=-1;
if(T!
=NULL)//树不空根结点入栈
{
T->mark=0;
push(s,*T);
}
BiTNode*p;//工作指针
while(s.top!
=-1)//栈不空
{p=&s.data[s.top];
while(p)
{
if(p->Lchild!
=NULL&&p->mark==0)//表明还没走左的
{
//左孩子入栈,直到走到尽头
p->mark=1;//表明从左进来的
p->Lchild->mark=0;
push(s,*p->Lchild);
p=&s.data[s.top];
}
else
break;
}
if(s.top!
=-1)
{
p=&s.data[s.top];
if(p->mark==2)//从右子回来,才输出
{
printf("%c",*p);
pop(s);
}
else
{
p->mark=2;//是从右进入的
if(p->Rchild!
=NULL)
push(s,*p->Rchild);//右孩子入栈
}
}
}
}
//按竖向树状显示二叉树的树状结构
voidPrintTree(BiTreeT,intlayer)
{
inti;
if(T==NULL)return;
PrintTree(T->Rchild,layer+1);
for(i=0;iprintf("");
printf("%c\n\n",T->data);
PrintTree(T->Lchild,layer+1);
}
voidpre_order(BiTreeT)
{
intx;
printf("\t\t*************************\n");
printf("\t\t*1--递归先序遍历*\n");
printf("\t\t*2--非递归先序遍历*\n");
printf("\t\t*************************\n");
printf("请输入你的选项:
");
scanf("%d",&x);
switch(x)
{
case1:
printf("此二叉树的先序递归遍历是:
");
preorder(T);
break;
case2:
printf("此二叉树的先序非递归遍历是:
");
stackpreorder(T);
break;
default:
printf("error!
\n");
break;
}
}
voidin_order(BiTreeT)
{
intx;
printf("\t\t*************************\n");
printf("\t\t*1--递归中序遍历*\n");
printf("\t\t*2--非递归中序遍历*\n");
printf("\t\t*************************\n");
printf("请输入你的选项:
");
scanf("%d",&x);
switch(x)
{
case1:
printf("此二叉树的中序递归遍历是:
");
inorder(T);
break;
case2:
printf("此二叉树的中序非递归遍历是:
");
stackinorder(T);
break;
default:
printf("error!
\n");
break;
}
}
voidpost_order(BiTreeT)
{
intx;
printf("\t\t*************************\n");
printf("\t\t*1--递归后序遍历*\n");
printf("\t\t*2--非递归后序遍历*\n");
printf("\t\t*************************\n");
printf("请输入你的选项:
");
scanf("%d",&x);
switch(x)
{
case1:
printf("此二叉树的后序递归遍历是:
");
postorder(T);
break;
case2:
printf("此二叉树的后序非递归遍历是:
");
stackpostorder(T);
break;
default:
printf("error!
\n");
break;
}
}
intmain()
{
BiTreeT=NULL;
intdep;
intlayer=0;//层数
intx,y=1;
while(y)
{
printf("\n");
printf("\t\t二叉树子系统\n");
printf("\t\t*************************\n");
printf("\t\t*1--建立一棵二叉树*\n");
printf("\t\t*2--先序遍历二叉树*\n");
printf("\t\t*3--中序遍历二叉树*\n");
printf("\t\t*4--后序遍历二叉树*\n");
printf("\t\t*5--二叉树的叶子数*\n");
printf("\t\t*6--输出二叉树的深度*\n");
printf("\t\t*7--显示二叉树*\n");
printf("\t\t*0--返回*\n");
printf("\t\t*************************\n");
printf("提示:
空用'#'表示:
\n");
printf("请输入你的选项:
");
scanf("%d",&x);
printf("\n");
switch(x)
{
case1:
system("cls");
printf("按先序序列输入:
\n");
printf("请输入该树的根结点:
");
Create(T);
printf("\n您的树已经建立好!
\n\n");
break;
case2:
system("cls");
pre_order(T);
printf("\n");
break;
case3:
system("cls");
in_order(T);
printf("\n");
break;
case4:
system("cls");
post_order(T);
printf("\n");
break;
case5:
printf("此二叉树的叶子结点为:
");
BiTreeleaf(T);
printf("\n此二叉树的叶子结点数为:
");
printf("%d\n",m);
break;
case6:
printf("此二叉树的深度为:
");
dep=Treehigh(T);
printf("%d",dep);
break;
case7:
system("cls");
printf("此二叉树的显示如下:
\n");
PrintTree(T,layer);
printf("\n");
break;
case0:
y=0;
break;
default:
printf("error!
\n");
break;
}
}
return0;
}
6、测试结果
(主界面)
(以上为第一棵树的所有操作)
(第二棵树的部分操作)
7、实验结论
通过本次实验的学习,不仅巩固了以前学过的知识,而且对二叉树的操作有了深刻的理解,使每一位小组成员都收获了很多。
具体学习了二叉树的建立,递归以及非递归的遍历思想,同时对于以前学过的顺序栈的操作也进一步的复习,对自己的编程水平有了很大的提高。
在实验中我们也发现了自己很多的不足。
课本上学到的知识当变成具体的程序时,又会遇到很多的问题,调试程序中遇见了很多问题,但是在团队协作的乐趣中,我们不畏错误,尝试着修改分析。
这样的过程中,我们的各方面在不断的提高,相信我们小组会越做越好。