二叉树和哈夫曼实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构实验报告
实验三二叉树的基本运算
一、实验目的
1、使学生熟练掌握二叉树的逻辑结构和存储结构。
2、熟练掌握二叉树的各种遍历算法。
二、实验内容
[问题描述]
建立一棵二叉树,试编程实现二叉树的如下基本操作:
1. 按先序序列构造一棵二叉链表表示的二叉树T;
2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列;
3. 求二叉树的深度/结点数目/叶结点数目;(选做)
4. 将二叉树每个结点的左右子树交换位置。(选做)
[基本要求]
从键盘接受输入(先序),以二叉链表作为存储结构,建立二叉树(以先序来建立),
[测试数据]
如输入:ABCффDEфGффFффф(其中ф表示空格字符)
则输出结果为
先序:ABCDEGF
中序:CBEGDFA
后序:CGEFDBA
层序:ABCDEFG
[选作内容]
采用非递归算法实现二叉树遍历。
三、总体设计
1.对程序中定义的核心数据结构及对其说明:
typedef struct Bintree
{
c har data;
B intree *lchild;
B intree *rchild;
}Bintree,*Bitree ;
在开头定义了二叉树的链式存储结构,此处采用了每个结点中设置三个域,即值域,左指针域和右指针域。
2.模块的划分及其功能:
本程序分为:7大模块。二叉树的建立链式存储结构、前序遍历、求叶子结点的个数计算、中序遍历、后序遍历、深度、主函数。
1、二叉树的建立链式存储结构;首先typedef struct Bintree:定义二叉树的链式存储结构,此处采用了每个结点中设置三个域,即值域,*lchild:左指针域和rchild:右指针域。
2、二叉树的前序遍历;利用二叉链表作为存储结构的前序遍历:先访问根结点,再依次访问左右子树。
3、二叉树的求叶子结点的个数计算;先分别求得左右子树中各叶子结点的
个数,再计算出两者之和即为二叉树的叶子结点数。
4、二叉树的中序遍历;利用二叉链表作为存储结构的中序遍历:先访问左
子数,再访问根结点,最后访问右子树。
5、二叉树的后序遍历;利用二叉链表作为存储结构的前序遍历:先访问左
右子树,再访问根结点。
6、求二叉树的深度:首先判断二叉树是否为空,若为空则此二叉树的深度
为0。否则,就先别求出左右子树的深度并进行比较,取较大的+1
就为二叉树的深度。
7、主函数。
核心算法的设计:二叉树是n个节点的有穷个集合,它或者是空集(n=0),或者同时满足以下两个条件:(1):有且仅有一个称为根的节点;(2):其余节点分为两个互不相交的集合T1,T2,并且T1,T2都是二叉树,分别称为根的左子树和右子树。
四、详细设计
1、存储结构的建立由CreatTree函数实现:
一、首先输入的是根结点;
二、然后输入的是根结点的左孩子;
三、再者输入的是根结点的右孩子;
四、接着输入的是根结点左孩子的左孩子;
五、输入的是根结点的左孩子的;
六、输入的是根结点的右孩子的左孩子;
七、输入的是根结点的右孩子的左孩子;
八、最后输入的是根结点的右孩子的右孩子。依次输入数据。
具体函数实现如下:
void CreatTree(Bitree &t,char a[])
{
if(a[sp]=='*')
{
t=NULL;
sp++;
}
else
{
t=new Bintree;
if(!t)
exit(0);
t->data=a[sp++];
CreatTree(t->lchild,a);
CreatTree(t->rchild,a);
}
}
在创建的二叉树中,左右孩子都为字符型。
char的作用是输入n个任意的字符,而且在输入n个字符后,必须输入N+1个0,才能得到本程序所有能够实现的功能。T=Null是将二叉树置为空。
if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))//采用动态申请新结点的方式,不仅实现起来方便,而且还节省大量的存储空间。
T->data=ch;值域
T->lchild=Create(T->lchild);左指针域
T->rchild=Create(T->rchild);右指针域
将二叉树中的每一个结点设置为:值域,左指针域,右指针。
这一小段程序实现了二叉树的置空,二叉树的建立,二叉树的存储。
2、前序遍历:先访问根结点,再访问左子树,最后访问右子树。
具体实现如下:
void Preorder(Bitree &t)
{
if(t!=NULL)
{
printf("%c",t->data);
Preorder(t->lchild);
Preorder(t->rchild);
}
}
3、求叶子结点的个数:
具体实现如下:
int Leaves_Num(Bitree &t)
{
if(t)
{
if(t->lchild==NULL&&t->rchild==NULL)
{
return 1;
}
return Leaves_Num(t->lchild)+Leaves_Num(t->rchild );
}
return 0;
}
4、中序遍历:先访问左子树,再访问根结点,最后访问右子树。
具体实现如下:
void Inorder(Bitree &t)
{
if(t!=NULL)
{
Inorder(t->lchild);
printf("%c",t->data);
Inorder(t->rchild);
}
}
5.后序遍历:先访问左子树,再访问右子树,最后访问根结点。
具体实现如下:
void Posorder(Bitree &t)
{
if(t!=NULL)
{
Posorder(t->lchild);
Posorder(t->rchild);
printf("%c",t->data);
}
}
6.求二叉树的深度: