数据结构实验三二叉树实验报告.docx
《数据结构实验三二叉树实验报告.docx》由会员分享,可在线阅读,更多相关《数据结构实验三二叉树实验报告.docx(13页珍藏版)》请在冰豆网上搜索。
数据结构实验三二叉树实验报告
数据结构实验报告
实验名称:
实验三——二叉树
学生姓名:
XX
班级:
班内序号:
学号:
日期:
1.实验要求
1.1实验目的
通过选择下面两个题目之一进行实现,掌握如下内容:
Ø掌握二叉树基本操作的实现方法
Ø了解赫夫曼树的思想和相关概念
Ø学习使用二叉树解决实际问题的能力
1.2实验内容
根据二叉树的抽象数据类型的定义,使用二叉链表实现一个二叉树。
二叉树的基本功能:
1、二叉树的建立
2、前序遍历二叉树
3、中序遍历二叉树
4、后序遍历二叉树
5、按层序遍历二叉树
6、求二叉树的深度
7、求指定结点到根的路径
8、二叉树的销毁
9、其他:
自定义操作
编写测试main()函数测试线性表的正确性
2.程序分析
2.1存储结构
2.2关键算法分析
(1)创建一个二叉树
伪代码实现:
1.定义根指针,输入节点储存的data,若输入“#”,则该节点为空;
2.申请一个新节点,判断它的父结点是否不为空,如果不为空在判断其为左或者右孩子,并把地址付给父结点,把data写入。
代码实现
voidBiTree:
:
create(BiNode*&R,intdata[],inti,intn)//创建二叉树
{
if(i<=n)
{
R=newBiNode;
R->data=data[i-1];
create(R->lch,data,2*i,n);
create(R->rch,data,2*i+1,n);
}
elseR=NULL;
}
(2)前序遍历
伪代码实现:
1.设置递归边界条件:
ifroot==null则停止递归
2.打印起始节点的值,并先后在左子数右子数上递归调用打印函数
代码实现
voidBiTree:
:
preorder(BiNode*R)//前序遍历
{
if(R!
=NULL)
{cout<data;
preorder(R->lch);
preorder(R->rch);
}
}
时间复杂度:
O(n)
(3)中序遍历
伪代码实现:
1.设置递归边界条件:
ifroot==null则停止递归
2.递归遍历左子树
3.打印根节点数据域内容
4.递归遍历右子树
代码实现
voidBiTree:
:
inorder(BiNode*R)//中序遍历
{
if(R!
=NULL)
{inorder(R->lch);
cout<data;
inorder(R->rch);
}
}
时间复杂度:
O(n)
(4)后序遍历
伪代码实现:
1.设置递归边界条件:
ifroot==null则停止递归
2.递归遍历左子树
3.递归遍历右子树
4.访问根结点数据域
代码实现
voidBiTree:
:
postorder(BiNode*R)//后序遍历
{
if(R!
=NULL)
{postorder(R->lch);
postorder(R->rch);
cout<data;
}
}
时间复杂度:
O(n)
(5)层序遍历
伪代码实现
1.队列Q及所需指针的定义和初始化
2.如果二叉树非空,将根指针入队
3.循环直到队列Q为空
3.1q=队列Q的队头元素出队
3.2访问节点q的数据域cout<data<<"";
3.3若节点q存在左孩子,则将左孩子指针入队
3.4若节点q存在右孩子,则将右孩子指针入队
代码实现
voidBiTree:
:
levelordre(BiNode*R)//层序遍历
{
BiNode*queue[maxsize];
intf=0,r=0;
if(R!
=NULL)
queue[++r]=R;
while(f!
=r)
{BiNode*p=queue[++f];
cout<data;
if(p->lch!
=NULL)
queue[++r]=p->lch;
if(p->rch!
=NULL)
queue[++r]=p->rch;
}
}
时间复杂度:
O(n)
(6)计算二叉树深度
伪代码实现:
1.定义和初始化计数深度的参数
2.如果根节点为空,return0
3.如果根节点为非空,递归调用自身的到叶子节点到根的路径长度,输出其中较大的作为树的深度
代码实现
intBiTree:
:
depth(BiNode*root)//求二叉树深度
{
intld,rd;
if(root!
=NULL)
{ld=1+depth(root->lch);
rd=1+depth(root->rch);
returnld>rd?
ld:
rd;
}
elsereturn0;
}
时间复杂度:
O(n)
(7)输出指定结点到根结点的路径
伪代码实现:
1.建立一个存储路径结点结构,定义和初始化结构体的数组
2.当root不为空或top为0时,进入循环
3.当此时root所指的节点的数据不为指定数据时,将root指向它的左孩子
4.当此时root所指的节点的数据为指定数据时,访问其数据域并输出
代码实现
boolBiTree:
:
printPath(BiNode*root,intdata)//打印指定结
点到根节点的路径
{
if(root==NULL)
returnfalse;
if(root->data==data||printPath(root->lch,data)||
printPath(root->rch,data))
{
cout<data;
returntrue;
}
returnfalse;
}
3.程序运行结果
3.1测试主函数流程图:
3.2测试条件
对如下二叉树:
补全后的二叉树:
按层序遍历的输入方法为:
ABC#EFGH###I###J###@
3.3程序运行结果为:
4.总结
出现的问题及改进:
刚开始编译正确但是输出结果异常,纪念馆仔细检查发现二叉树创建有问题,经过仔细修改,发现形参表示错误,*&,指针的引用,作为输入时,既把指针的值传入函数内部,又可以将指针的关系传递到函数内部;作为输出,由于算法中修改了指针的值,可以将新值传入到函数内部。
心得体会;掌握二叉树基本操作的实现方法
下一步改进:
除了递归的方法,试着用非递归的方法解决二叉树的相关问题。
附:
源代码
#include
usingnamespacestd;
constintmaxsize=100;
structBiNode
{intdata;
BiNode*lch;
BiNode*rch;
};
classBiTree
{private:
voidcreate(BiNode*&R,intdata[],inti,intn);
voidrelease(BiNode*R);
public:
BiNode*root;
BiTree(intdata[],intn);
voidpreorder(BiNode*R);
voidinorder(BiNode*R);
voidpostorder(BiNode*R);
voidlevelordre(BiNode*R);
intdepth(BiNode*root);
boolprintPath(BiNode*root,intdata);
~BiTree();
};
voidBiTree:
:
create(BiNode*&R,intdata[],inti,intn)//创
建二叉树
{
if(i<=n)
{
R=newBiNode;
R->data=data[i-1];
create(R->lch,data,2*i,n);
create(R->rch,data,2*i+1,n);
}
elseR=NULL;
}
BiTree:
:
BiTree(intdata[],intn)//构造函数
{create(root,data,1,n);
}
voidBiTree:
:
preorder(BiNode*R)//前序遍历
{
if(R!
=NULL)
{cout<data;
preorder(R->lch);
preorder(R->rch);
}
}
voidBiTree:
:
inorder(BiNode*R)//中序遍历
{
if(R!
=NULL)
{inorder(R->lch);
cout<data;
inorder(R->rch);
}
}
voidBiTree:
:
postorder(BiNode*R)//后序遍历
{
if(R!
=NULL)
{postorder(R->lch);
postorder(R->rch);
cout<data;
}
}
voidBiTree:
:
levelordre(BiNode*R)//层序遍历
{
BiNode*queue[maxsize];
intf=0,r=0;
if(R!
=NULL)
queue[++r]=R;
while(f!
=r)
{BiNode*p=queue[++f];
cout<data;
if(p->lch!
=NULL)
queue[++r]=p->lch;
if(p->rch!
=NULL)
queue[++r]=p->rch;
}
}
intBiTree:
:
depth(BiNode*root)//求二叉树深度
{
intld,rd;
if(root!
=NULL)
{ld=1+depth(root->lch);
rd=1+depth(root->rch);
returnld>rd?
ld:
rd;
}
elsereturn0;
}
boolBiTree:
:
printPath(BiNode*root,intdata)//打印指定结
点到根节点的路径
{
if(root==NULL)
returnfalse;
if(root->data==data||printPath(root->lch,data)||
printPath(root->rch,data))
{
cout<data;
returntrue;
}
returnfalse;
}
voidBiTree:
:
release(BiNode*R)//释放二叉树
{if(R!
=NULL)
{release(R->lch);
release(R->rch);
deleteR;
}
}
BiTree:
:
~BiTree()//析构函数
{release(root);
}
voidmain()//主函数
{inta[7]={1,2,3,4,5,6,7};
BiTreeA(a,7);
BiNode*Q=A.root;
cout<<"前序遍历";
A.preorder(Q);
cout<cout<<"中序遍历";
A.inorder(Q);
cout<cout<<"后序遍历";
A.postorder(Q);
cout<cout<<"层序遍历";
A.levelordre(Q);
cout<intx;
x=A.depth(Q);
cout<<"二叉树深度"<cout<inty=4;
cout<<"指定结点"<"<A.printPath(Q,y);
cout<A.~BiTree();
}