数据结构二叉树的递归算法实验报告讲解.docx
《数据结构二叉树的递归算法实验报告讲解.docx》由会员分享,可在线阅读,更多相关《数据结构二叉树的递归算法实验报告讲解.docx(15页珍藏版)》请在冰点文库上搜索。
数据结构二叉树的递归算法实验报告讲解
齐鲁工业大学实验报告成绩
课程名称数据结构指导教师单健芳实验日期
院(系)信息学院专业班级计科(嵌入)14-1实验地点
学生姓名高晨悦学号201403071007同组人无
实验项目名称二叉树的递归算法
一、实验目的和要求
1.实现二叉树的先序,中序与后序遍历的递归算法与非递归算法。
2.求二叉树的结点个数,叶子结点个数,二叉树的高度,度为2的结点个数。
二、实验环境
微型计算机vc6.0
三、实验内容
1.实现二叉树的先序,中序与后序遍历的递归算法与非递归算法。
2.求二叉树的结点个数,叶子结点个数,二叉树的高度,度为2的结点个数。
四、实验步骤
一.实验内容
1.实现二叉树的先序,中序与后序遍历的递归算法与非递归算法。
2.求二叉树的结点个数,叶子结点个数,二叉树的高度,度为2的结点个数。
二.程序的设计思想
1实现二叉树的先序,中序与后序遍历的递归算法与非递归算法。
先构造二叉树,根据先序遍历的思想,输入根后,再输入左子树,直至左子树为空则输入上一层右字树。
(1)二叉树的非递归遍历是用显示栈来存储二叉树的结点指针,先序遍历时,按二叉树前序遍历的顺序访问结点,并将结点的指针入栈,直到栈顶指针指向结点的左指针域为空时取出栈顶指针并删除栈顶指针,访问刚取出的指针指向的结点的右指针指向的结点并将其指针入栈,如此反复执行则为非递归操作。
(2)二叉树的递归遍历:
若二叉树为空,则空操作
先序遍历:
(a)访问根结点;
(b)先序遍历左子树;
(c)先序遍历右子树。
中序遍历:
(a)中序遍历左子树;
(b)访问根结点;
(c)中序遍历右子树
后序遍历:
(a)后序遍历左子树;
(b)后序遍历右子树;
(c)访问根结点。
2.求二叉树的结点个数,叶子结点个数,二叉树的高度,度为2的结点个数。
(1)求二叉树的叶子结点个数:
先分别求得左右子树中个叶子结点的个数,再计算出两者之和即为二叉树的叶子结点数。
(2)二叉树的结点个数之和:
先分别求得左子树右子树中结点之和,再计算两者之和即为所求。
(3)二叉树的高度:
首先判断二叉树是否为空,若为空则此二叉树高度为0,。
否则,就先分别求出左右子树的深度进行比较,取较大的树加一即为所求。
(4)二叉树的度为2的结点个数:
计算有左右孩子的结点个数,即为度为2的结点个数。
三.编程过程中遇到的问题及解决办法
(1)后续遍历的非递归函数涉及到回溯的方法,开始设计的方案想的太过于简单,所以形成了死循环,总是在最后的节点处不停地循环,后改成回溯后,该问题得到解决。
(2)计算二叉树中度为2的结点个数中,返回循环的时候不论根结点有没有左右子树,但个人设计时,根总是会将自己默认为有左右子树,自行增加1.后在同学帮助下才看到自己的这个失误。
四.程序的闪光点(自我评价)
1.程序模块化,各个函数分开描述,方便观察
2.关键处有注释
3.建立二叉树时,用先序提示输入,比较人性化。
五.程序源代码(以文件为单位提供)
#include
#include
#defineMaxsize100
typedefstructTREE{
structTREE*lTree;
structTREE*rTree;
chardata;
}Tree;
voidInitTree(Tree*);//初始化树
voidCreatTree(Tree*);//创建二叉树
voidPreTraverse(Tree*);//先序遍历递归
voidPreOrderTraverse(Tree*);//先序遍历非递归
voidInTraverse(Tree*tree);//中序遍历递归
voidInOrderTraverse(Tree*tree);//中序遍历非递归
voidPostTraverse(Tree*tree);//后序遍历递归
voidLastOrderTraverse(Tree*tree);//后序遍历非递归
intDepthTree(Tree*tree);//计算树的深度
intLeafsTree(Tree*tree);//计算叶子结点个数
intNodesTree(Tree*tree);//计算结点个数
intTwochild(Tree*tree);//计算度为二的结点个数
voidmain()
{
intH,L;
Treetree;
//Treem;
InitTree(&tree);
CreatTree(&tree);
cout<<"先序遍历递归为:
";
PreTraverse(&tree);//先序遍历递归
cout<<"先序遍历非递归:
";
PreOrderTraverse(&tree);//先序遍历非递归
cout<cout<<"中序遍历递归为:
";
InTraverse(&tree);//中序遍历递归
cout<<"中序遍历非递归:
";
InOrderTraverse(&tree);//中序遍历非递归
cout<cout<<"后序遍历递归为:
";
PostTraverse(&tree);//后序遍历递归
cout<<"后序遍历非递归:
";
LastOrderTraverse(&tree);//后序遍历非递归
cout<cout<<"树的深度为:
";
H=DepthTree(&tree);
cout<cout<<"叶子结点个数:
";
L=LeafsTree(&tree);
cout<cout<<"结点个数:
";
cout<cout<<"度为二的结点个数";
L=Twochild(&tree);
cout<}
voidInitTree(Tree*tree)//初始化树
{
tree->lTree=NULL;
tree->rTree=NULL;
tree->data='0';
}
voidCreatTree(Tree*tree)//创建树
{
intn=0,m=0,i=0;
if(tree->data=='0')
{
cout<<"请输入该节点的数据:
";
cin>>tree->data;
}
cout<<"节点"<data<<"是否有左子树(0:
没有1:
有):
";
cin>>n;
if(n==1)
{
Tree*lTree=(Tree*)malloc(sizeof(Tree));
tree->lTree=lTree;
lTree->lTree=NULL;
lTree->rTree=NULL;
lTree->data='0';
CreatTree(tree->lTree);
cout<<"节点"<data<<"是否有右子树(0:
没有1:
有):
";
cin>>i;
if(i==0);
elseif(i==1)
{
Tree*rTree=(Tree*)malloc(sizeof(Tree));
tree->rTree=rTree;
rTree->lTree=NULL;
rTree->rTree=NULL;
rTree->data='0';
CreatTree(tree->rTree);
}
}
elseif(n==0)
{
cout<<"节点"<data<<"是否有右子树(0:
没有1:
有):
";
cin>>m;
if(m==0);
elseif(m==1)
{
Tree*rTree=(Tree*)malloc(sizeof(Tree));
tree->rTree=rTree;
rTree->lTree=NULL;
rTree->rTree=NULL;
rTree->data='0';
CreatTree(tree->rTree);
}
}
}
voidPreTraverse(Tree*tree)//先序遍历递归
{
if(tree!
=NULL)
{
cout<data<<"";
if(tree->lTree!
=NULL)
{
PreTraverse(tree->lTree);
PreTraverse(tree->rTree);
}
elseif(tree->rTree!
=NULL)
{
PreTraverse(tree->rTree);
}
else;
}
}
voidPreOrderTraverse(Tree*tree)//先序遍历非递归
{
Tree*S[80]={NULL};
inttop=0;
while((tree!
=NULL)||(top))
{
if(tree!
=NULL)
{
cout<data<<"";
top++;
S[top]=tree;
tree=tree->lTree;
}
else
{
tree=S[top];
top--;
tree=tree->rTree;
}
}
}
voidInTraverse(Tree*tree)//中序遍历递归
{
if(tree!
=NULL)
{
if(tree->lTree!
=NULL)
{
InTraverse(tree->lTree);
cout<data<<"";
InTraverse(tree->rTree);
}
elseif(tree->rTree!
=NULL)
{
cout<data<<"";
InTraverse(tree->rTree);
}
else
cout<data<<"";
}
}
voidInOrderTraverse(Tree*tree)//中序遍历非递归
{
Tree*D[80]={NULL};
inttop=0;
while((tree!
=NULL)||(top))
{
if(tree!
=NULL)
{
top++;
D[top]=tree;
tree=tree->lTree;
}
else
{
tree=D[top];
top--;
cout<data<<"";
tree=tree->rTree;
}
}
}
voidPostTraverse(Tree*tree)//后序遍历递归
{
if(tree!
=NULL)
{
if(tree->lTree!
=NULL)
{
PostTraverse(tree->lTree);
PostTraverse(tree->rTree);
cout<data<<"";
}
elseif(tree->rTree!
=NULL)
{
PostTraverse(tree->rTree);
cout<data<<"";
}
else
cout<data<<"";
}
}
voidLastOrderTraverse(Tree*tree)//后序遍历非递归
{
Tree*stack[Maxsize]={NULL},*p;
p=tree;
inttop=0,tag=1,i=0,k=0;
while(p!
=NULL||top)
{
i=1;
while(p!
=NULL)
{
stack[++top]=p;
p=p->lTree;
}
if(top!
=0)
p=stack[top]->rTree;
if(p==NULL)
{
cout<data<<"";
if(stack[top]!
=NULL)
{
while(i)
{
if(stack[top]!
=NULL)
{
if(stack[top]->rTree!
=NULL)
{
if(stack[top]->rTree->data==stack[top+1]->data)
cout<data<<"";
else
i=0;
}
else
i=0;
}
else
i=0;
}
}
if(top!
=0)
p=stack[top]->rTree;
else
p=NULL;
}
}
}
intDepthTree(Tree*tree)//深度函数
{
intu,v;
if(tree==NULL)return0;
u=DepthTree(tree->lTree);
v=DepthTree(tree->rTree);
if(u>v)
return(u+1);
return(v+1);
}
intLeafsTree(Tree*tree)//子叶个数函数
{
intnum1,num2;
if(tree==NULL)
return0;
elseif(tree->lTree==NULL&&tree->rTree==NULL)
return1;
else
{
num1=LeafsTree(tree->lTree);
num2=LeafsTree(tree->rTree);
return(num1+num2);
}
}
intNodesTree(Tree*tree)//结点个数函数
{
intnum1,num2;
if(tree==NULL)
return0;
if(tree->lTree==NULL&&tree->rTree==NULL)
return1;
else
{
num1=NodesTree(tree->lTree);
num2=NodesTree(tree->rTree);
return(num1+num2+1);
}
}
intTwochild(Tree*tree)//度为2的
{
intn=0;
if(tree==NULL)
return(0);
if(tree->lTree!
=NULL&&tree->rTree!
=NULL)
n=1;
return(Twochild(tree->lTree)+Twochild(tree->rTree)+n);
}
5、讨论、心得
通过这次实验使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。