XXX大学
课 程 设 计
课 程 数据结构课程设计
题 目 哈夫曼树构造及编码
系 别 信息工程学院
专 业 软件工程
班 级
姓 名
学 号
学年学期
年 月 日
课程设计任务书
题目 哈夫曼树的构造及编码
班级 2017级软件工程三班
学号 姓名
学号 姓名
学号 姓名
- 设计目的:
(一)要求学生通过本环节的充分编程实践和实际应用,进一步熟悉与巩固C语言语法知识和程序设计的基本方法。
(二)通过分析、设计、编码、调试等环节的训练,使学生深刻理解、牢固掌握数据结构和算法设计技术,掌握分析、解决实际问题的能力。
(三)借助适当题材的程序设计实训,加深体会利用数据结构的算法和C语言程序设计解决实际问题的基本环节的思维过程。
(四)利用适当形式的命题,加深体会结构化程序设计的方法,掌握自顶向下、逐步细化的编程思维方式。
(五)通过一定的文档要求,使学生掌握良好的程序设计风格,包括程序结构形式,行文格式和程序正文格式等。
- 任务要求:
(一)质量要求
1.资料充分,结构完整,论述清晰。
2.重要数据引用他人成果要标明出处。
3.符合我院课程设计撰写规范。
4.按时完成课程设计各阶段工作,不突击,不抄袭。
- 进度要求
1.明确课程设计任务,搜集资料:2018年12月16日--2018年12月19日。
2.完成课程设计实践内容:2018年12月20日--2018年12月21日。
3.完成课程设计报告:2018年12月22日--2018年12月23日。
- 主要参考资料:
[1] 邓又明,数据结构(第一版),北京,地质出版社,2007年8月。
[2] 刘天印,C语言程序设计(第一版),北京,科学出版社,2007年3月。
- 严蔚敏,吴伟民编著,数据结构(C语言版),北京;清华大学出版社,2005。
- 严蔚敏,陈文博编著,数据结构及应用算法教程,北京;清华大学出版社,2006。
[5]谭浩强编著,C语言程序设计 (第二版),北京;清华大学出版社,2003。
指导教师签名:
年 月 日
目录
1概述............................................................................................ 5
1.1题目要求............................................................................ 5
1.2课程设计分工情况 .............................................................5
2 问题分析和算法思路 ..................................................................6
3 编码 ...........................................................................................7
3.1 数据结构定义 ...................................................................7
3.2 功能函数设计 ...................................................................8
3.3 程序流程图 .......................................................................8
3.4 程序实现 ..........................................................................10
4 测试 ..........................................................................................12
4.1 测试用例 ..........................................................................12
4.2 程序运行结果 ...................................................................13
设计体会 ......................................................................................14
1概述
1.1题目要求
理解和掌握课堂上所学各种基本抽象数据类型的逻辑结构、存储结构和操作实现算法,以及它们在程序中的使用方法,具备初步的独立分析和设计能力。初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能。提高综合运用所学的理论知识和方法独立分析和解决问题的能力。训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。使学生掌握软件设计的基本内容和设计方法,并培养学生进行规范化软件设计的能力。使学生掌握使用各种计算机资料和有关参考资料,提高学生程序设计能力。
1.2课程设计分工情况
本组共有3人,具体分工情况如下:
(1)学号: ,姓名: ,具体负责编码和测试工作。
(2)学号: ,姓名: ,具体负责总体设计和详细设计工作。
(3)学号: ,姓名: ,具体负责问题分析和算法思路工作。
2 问题分析和算法思路
哈夫曼树,给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
哈夫曼编码,在数据通信中,需要将传送的文字转换成二进制的字符串,用0,1码的不同排列来表示字符。例如,需传送的报文为“AFTER DATA EAR ARE ART AREA”,这里用到的字符集为“A,E,R,T,F,D”,各字母出现的次数为{8,4,5,3,1,1}。现要求为这些字母设计编码。要区别6个字母,最简单的二进制编码方式是等长编码,固定采用3位二进制,可分别用000、001、010、011、100、101对“A,E,R,T,F,D”进行编码发送,当对方接收报文时再按照三位一分进行译码。然而,传送报文时总是希望总长度尽可能短。在实际应用中,各个字符的出现频度或使用次数是不相同的,如A、B、C的使用频率远远高于X、Y、Z,自然会想到设计编码时,让使用频率高的用短码,使用频率低的用长码,以优化整个报文编码。
为使不等长编码为前缀编码(即要求一个字符的编码不能是另一个字符编码的前缀),可用字符集中的每个字符作为叶子结点生成一棵编码二叉树,为了获得传送报文的最短长度,可将每个字符的出现频率作为字符结点的权值赋予该结点上,显然字使用频率越小权值越小,权值越小叶子就越靠下,于是频率小编码长,频率高编码短,这样就保证了此树的最小带权路径长度效果上就是传送报文的最短长度。因此,求传送报文的最短长度问题转化为求由字符集中的所有字符作为叶子结点,由字符出现频率作为其权值所产生的哈夫曼树的问题。利用哈夫曼树来设计二进制的前缀编码,既满足前缀编码的条件,又保证报文编码总长最短。
哈夫曼树的构造,假设有n个权值,则构造出的哈夫曼树有n个叶子结点。 n个权值分别设为 w1、w2、…、wn,则哈夫曼树的构造规则为:
(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);
(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;
(3)从森林中删除选取的两棵树,并将新树加入森林;
(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。
哈夫曼编码的回溯步骤:
(1)选出哈夫曼树的某一个叶子结点。
(2)利用其双亲指针parent找到其双亲结点。
(3)利用找到的双亲结点的指针域中的lchild和rchild,判断该结点是双亲的左孩子还是右孩子。若该结点是其双亲结点的左孩子,则生成代码0;若该结点是其双亲结点的右孩子,则生成代码1。
(4)由于生成的编码与要求的编码反序,将所生成的编码反序。
(5)重复步骤(1)~(4),直到所有结点都回溯完。
3 编码
3.1 数据结构定义
哈夫曼树的构造用的是线性结构,顺序存储:
typedef struct
{
char data[5]; //结点值
double weight; //权重
int parent; //双亲结点
int lchild; //左孩子结点
int rchild; //右孩子结点
} HTNode;
哈弗曼编码的数据结构类型也是顺序存储:
typedef struct
{
char cd[N]; //存放哈夫曼码
int start;
} HCode;
3.2 功能函数设计
(1) CreateHT函数:构造哈夫曼树
(2) CreateHCode函数:构造哈夫树曼编码
(3) DispHCode函数:输出哈夫曼树编码
3.3 程序流程图
图一 哈夫曼构建流程图
图二 哈夫曼编码流程图
3.4 程序实现
源代码:https://blog.csdn.net/queen00000/article/details/94472256
4 测试
4.1 测试用例
int main()
{
int n=8,i; //n表示初始字符串的个数
char *str[]={"a","b","c","d","e","f","g","h"};
double fnum[]={0.07,0.19,0.02,0.06,0.32,0.03,0.21,0.1};
HTNode ht[M];
HCode hcd[N];
for (i=0;i<n;i++)
{
strcpy(ht[i].data,str[i]);
ht[i].weight=fnum[i];
}
printf("\n");
CreateHT(ht,n);
CreateHCode(ht,hcd,n);
DispHCode(ht,hcd,n);
printf("\n");
return 1;
}
4.2 程序运行结果
设计体会
对于本次课程设计,主要是需要掌握哈夫曼树建立和哈夫曼编码的算法。并能将其熟练应用于编译码器的完成。经过这次的课程设计,使我们更加了解了数据结构,也更深入地了解了哈夫曼编码的算法,课程设计的题目比我们平常的实验内容要难一些,完成它不仅需要有厚实的语言基础,而且还要熟练掌握哈夫曼编码的算法。
我从实践中明白了C语言的模块化设计的理论。将一个大任务分成若干个较小的任务,较小的任务又细分为更小的任务,直到更小的任务功能较为单一,便于实现为止,每个小任务为一个模块。各个模块功能单一,独立编程,独立存放,单独调试,可以为多个程序所调用,并可以由不同的人实现。在以后的编程过程中,我会按照软件开发的方法,步骤,原则认真的完成软件开发。不断寻求最优的解决问题的办法,使自己开发出来的软件运行效率更高,功能更加完善。对于自己解决不了的问题可以在网上查找,找同学帮忙,复习教材相应的内容,并且不断地学习新知识,以使自己在软件开发方面跟上时代的发展。