数据结构实验二叉树遍历.docx
《数据结构实验二叉树遍历.docx》由会员分享,可在线阅读,更多相关《数据结构实验二叉树遍历.docx(12页珍藏版)》请在冰豆网上搜索。
数据结构实验二叉树遍历
深圳大学实验报告
课程名称:
数据结构
实验项目名称:
树状结构之二叉树遍历
学院:
信息工程学院
专业:
电子信息工程
指导教师:
报告人:
学号:
2009100000班级:
电子1班
实验时间:
2011年11月10日
实验报告提交时间:
2011年11月15日
教务处制
一、实验目的与要求:
实验目的:
通过运用二叉树知识,编程实现二叉树遍历以及相关应用,从而加深对二叉树概念的理解,提高二叉树的编程应用技巧
实验要求:
阅读程序框架代码,完成以下要求
a)填写PreOrder(BiTreeNode*&t)、InOrder(BiTreeNode*&t)、PostOrder(BiTreeNode*&t)三个函数的代码
b)运行程序输入测试数据,正确输出三种遍历的结果,结果图看示例
附加1、编写程序通过遍历求二叉树的左子树数目
附加2:
编写程序采用一种遍历,能够搜索出二叉树包含多少叶子,输入测试数据并显示正确结果,要有代码分析和运行结果图
二、方法、步骤:
1、通过二叉树先序、中序、后序三种遍历的算法思路编写可遍历程序
2、基于二叉树遍历的程序框架代码,完成先序、中序、后序三种遍历的代码编写,输出先序、中序、后序三种遍历的结果。
3、可以在遍历过程中对结点进行各种操作。
例如在此实验中,对于所建好的
树可求结点孩子结点。
求树的叶子,还有对各结点的不同操作。
以上这些都是基于二叉树遍历的思想。
----------------------------------------------------------------------------------------------------
三.实验过程及内容:
(对程序代码进行说明和分析,越详细越好,代码排版要整齐,可读性要高)
一、程序如下:
其中,以下程序同时加上了附加题1:
#include
#include
usingnamespacestd;
intlchild_num;//左孩子的个数变量
classBiTreeNode
{
private:
BiTreeNode*leftChild;//左子树指针
BiTreeNode*rightChild;//右子树指针
public:
//构造函数和析构函数
BiTreeNode():
leftChild(NULL),rightChild(NULL){}
BiTreeNode(charitem,BiTreeNode*left=NULL,
BiTreeNode*right=NULL):
data(item),leftChild(left),rightChild(right){}
~BiTreeNode(){}
BiTreeNode*&Left(void)//注意返回值类型为指针的引用类型
{
if(leftChild!
=NULL)
lchild_num++;//若左子树不为空则加一
returnleftChild;
}
BiTreeNode*&Right(void)//注意返回值类型为指针的引用类型
{returnrightChild;}
};
classBiTree
{
private:
BiTreeNode*root;//根结点指针
inti;
voidDestroy(BiTreeNode*&t);
voidPreOrder(BiTreeNode*&t);
voidInOrder(BiTreeNode*&t);
voidPostOrder(BiTreeNode*&t);
voidCreateBiTree(BiTreeNode*&T,constcharstrTree[]);
voidget_lchild(BiTreeNode*&t);//获取左子树
public:
//构造函数和析构函数
BiTree(void):
root(NULL),i(0){}//构造函数
~BiTree(void){};//析构函数
//构造二叉树
voidMakeTree(constcharitem,BiTree&left,BiTree&right);//构造二叉树
voidMakeTree(constchartrTree[]);//构造二叉树,利用先序遍历结果建树
voidPreOrder();//前序遍历
voidInOrder();//中序遍历
voidPostOrder();//后序遍历
voidget_lchild1(void);//获取左子树
};
//定义建树函数
voidBiTree:
:
MakeTree(constcharitem,BiTree&left,BiTree&right)
//构造数据域为item,左子树为left,右子树为right的二叉树
{
root=newBiTreeNode(item,left.root,right.root);
}
voidBiTree:
:
MakeTree(constcharstrTree[])
//构造二叉树,利用先序遍历结果建树,公有函数
{
i=0;
CreateBiTree(root,strTree);
}
voidBiTree:
:
CreateBiTree(BiTreeNode*&T,constcharstrTree[])//递归建树私有函数
{
charch;
ch=strTree[i++];
if(ch=='0')T=NULL;//输入为,代表该孩子不存在,则返回
else
{
T=newBiTreeNode();//生成根结点
T->data=ch;
CreateBiTree(T->Left(),strTree);//构造左子树
CreateBiTree(T->Right(),strTree);//构造右子树
}
}
//定义先序遍历函数
voidBiTree:
:
PreOrder()
//前序遍历访问二叉树,公有函数
{
PreOrder(root);
}
voidBiTree:
:
PreOrder(BiTreeNode*&t)
//前序遍历访问二叉树,私有函数t
{
if(t!
=NULL)
{//如果树不为空,往下执行,如果为空,忽略不执行,返回上个结点
cout<data;//输出当前结点的数值
PreOrder(t->Left());//递归访问左孩子
PreOrder(t->Right());//递归访问右孩子
}
}
//定义中序遍历函数
voidBiTree:
:
InOrder()
//中序遍历访问二叉树,公有函数
{
InOrder(root);
}
voidBiTree:
:
InOrder(BiTreeNode*&t)
//中序遍历访问二叉树,私有函数t
{
if(t!
=NULL)
{//如果树不为空,往下执行,如果为空,忽略不执行,返回上个结点
InOrder(t->Left());//递归访问左孩子
cout<data;//输出当前结点的数值
InOrder(t->Right());//递归访问右孩子
}
}
//后序遍历函数
voidBiTree:
:
PostOrder()
//后序遍历访问二叉树,公有函数
{
PostOrder(root);
}
voidBiTree:
:
PostOrder(BiTreeNode*&t)
//后序遍历访问二叉树,私有函数t
{
if(t!
=NULL)
{//如果树不为空,往下执行,如果为空,忽略不执行,返回上个结点
PostOrder(t->Left());//递归访问左孩子
PostOrder(t->Right());//递归访问右孩子
cout<data;//输出当前结点的数值
}
}
//通过先序遍历求得左子树
voidBiTree:
:
get_lchild(BiTreeNode*&t)
//前序遍历访问二叉树,私有函数t
{
if(t!
=NULL)
{
get_lchild(t->Left());
get_lchild(t->Right());
}
}
//采用前序遍历的方法,求出左孩子的个数
voidBiTree:
:
get_lchild1(void)
{
lchild_num=0;
get_lchild(root);
cout<}
intmain(void)
{
charstrTree[80];
BiTreemyTree;
cout<<"请输入二叉树先序遍历结果,空子树用表示:
"<cin>>strTree;
myTree.MakeTree(strTree);
cout<<"先序遍历结果:
";
myTree.PreOrder();
cout<cout<<"中序遍历结果:
";
myTree.InOrder();
cout<cout<<"后序遍历结果:
";
myTree.PostOrder();
cout<cout<<"左孩子的个数:
";
myTree.get_lchild1();//返回左子树的个数
return0;
}
二、附加题二:
不使用类的方法实现遍历过程,找出所有结点并显示出来
#include
usingnamespacestd;
typedefstructnode*Bitree;
typedefstructnode//构建一个结构体
{
chardata;
structnode*lchild,*rchild;
}Node;
voidPreCreateBitree(Bitree*t)//建立二叉树
{
charch;
scanf("%c",&ch);
if(ch=='0')
*t=NULL;
else{
*t=(Node*)malloc(sizeof(Node));//生成新结点
(*t)->data=ch;
PreCreateBitree(&(*t)->lchild);//函数递归访问
PreCreateBitree(&(*t)->rchild);//函数递归访问
}
}
intleaf_node(BitreeT)
{
intm,n;
if(T==NULL)return0;//树为空则返回0
elseif(T->lchild==NULL&&T->rchild==NULL)
{//左子树和右子树都为空返回1
cout<<"叶子"<data;
cout<return1;
}
n=leaf_node(T->lchild);//左子树是叶子时
m=leaf_node(T->rchild);//右子树是叶子时
return(m+n);//返回左右叶子的和
}
//主函数
intmain()
{
intcount;//叶子数目
Bitreeroot;
cout<<"请输入二叉树先序遍历结果,空子树用表示:
"<PreCreateBitree(&root);//建立二叉树
count=leaf_node(root);
cout<<"叶子数目为:
"<return0;
}
四、实验结论:
(提供运行结果,对结果进行探讨、分析、评价,并提出结论性意见和改进想法)
一、程序一运行
结果图一、
结果图二、
程序一结果分析:
针对结果图一,对于中序遍历来分析:
1、首先通过先序遍历创建了二叉树ABC00D00E00
2、判断树是否为空,如果树不为空,往下执行,如果为空,忽略不执行,返回上个结点
3、递归访问左孩子InOrder(t->Left());
4、输出当前结点的数值cout<data;
5、递归访问右孩子InOrder(t->Right());
同理,后序遍历原理也基本一样。
二、程序二所运行结果图一、
程序二运行结果分析:
针对结果如图一来分析:
1、首先通过先序遍历创建二叉树ABC00D00E00
2、判断左子树和右子树都为空,是则说明已经是叶子,即叶子数目加一
3、若第二步不成立则通过递归函数继续访问直到第二步成立为止。
4、返回叶子数目
五、实验体会:
(根据自己情况填写)
直接看课本很简单,自己编程起来就比较吃力!
多编程是提高编程能力的唯一途径。
这个实验花了很多的时间,首先是要狠清楚遍历的算法,然后再试着慢慢编程,不断调试最后得出结果。
个人觉得,二叉树始终很灵活的算法,学好它用好它是很重要的。
还是提醒自己要多编程!
指导教师批阅意见:
成绩评定:
指导教师签字:
年月日
备注: