1、 数据结构 课程设计报告课 题: 哈夫曼编码译码器 专业班级: 信 息 06102 班 学 号: 200616020208 姓 名: 李 宇 光 指导教师: 屠 添 翼 目 录评阅意见:评定成绩:指导老师签名:年 月 日1目 录目录 11 课程设计的目的和意义 22 需求分析 33 系统(项目) 设计 5设计思路及方案5模块的设计及介绍5主要模块程序流程图84 系统实现 11主调函数12建立 HuffmanTree12生成 Huffman 编码并写入文件 15电文译码165 系统调试 17参考文献 20附录 源程序 2121 课程设计的目的和意义在当今信息爆炸时代,如何采用有效的数据压缩技术来
2、节省数据文件的存储空间和计算机网络的传送时间已越来越引起人们的重视。哈夫曼编码正是一种应用广泛且非常有效的数据压缩技术。哈夫曼编码的应用很广泛,利用哈夫曼树求得的用于通信的二进制编码称为哈夫曼编码。树中从根到每个叶子都有一条路径,对路径上的各分支约定:指向左子树的分支表示“0”码,指向右子树的分支表示“1”码,取每条路径上的“0”或“1”的序列作为和各个对应的字符的编码,这就是哈夫曼编码。通常我们把数据压缩的过程称为编码,解压缩的过程称为解码。电报通信是传递文字的二进制码形式的字符串。但在信息传递时,总希望总长度尽可能最短,即采用最短码。作为信息管理专业的学生,我们应该很好的掌握这门技术。在课
3、堂上,我们能过学到许多的理论知识,但我们很少有过自己动手实践的机会!课程设计就是为解决这个问题提供了一个平台。在课程设计过程中,我们每个人选择一个课题,认真研究,根据课堂讲授内容,借助书本,自己动手实践。这样不但有助于我们消化课堂所讲解的内容,还可以增强我们的独立思考能力和动手能力;通过编写实验代码和调试运行,我们可以逐步积累调试 C 程序的经验并逐渐培养我们的编程能力、用计算机解决实际问题的能力。在课程设计过程中,我们不但有自己的独立思考,还借助各种参考文献来帮助我们完成系统。更为重要的是,我们同学之间加强了交流,在对问题的认识方面可以交换不同的意见。同时,师生之间的互动也随之改善,我们可以
4、通过具体的实例来从老师那学到更多的实用的知识。数据结构课程具有比较强的理论性,同时也具有较强的可应用性和实践性。课程设计是一个重要的教学环节。我们在一般情况下都能够重视实验环节,但是容易忽略实验的总结,忽略实验报告的撰写。通过这次实验让我们明白:作为一名大学生必须严格训练分析总结能力、书面表达能力。需要逐步培养书写科学实验报告以及科技论文的能力。只有这样,我们的综合素质才会有好的提高。32 需求分析课 题:哈夫曼编码译码器系统问题描述:打开一篇英文文章,统计该文章中每个字符出现的次数,然后以它们作为权值,对每一个字符进行编码,编码完成后再对其编码进行译码。问题补充:1. 从硬盘的一个文件里读出
5、一段英语文章;2. 统计这篇文章中的每个字符出现的次数;3. 以字符出现字数作为权值,构建哈夫曼树,并将哈夫曼树的存储结构的初态和终态进行输出;4. 对每个字符进行编码并将所编码写入文件然后对所编码进行破译。具体介绍:在本课题中,我们在硬盘 E 盘中预先建立一个 file1.txt 文档,在里面编辑一篇文章(大写)。然后运行程序,调用 fileopen()函数读出该文章,显示在界面;再调用 jsq()函数对该文章的字符种类进行统计,并对每个字符的出现次数进行统计,并且在界面上显示;然后以每个字符出现次数作为权值,调用 ChuffmanTree()函数构建哈夫曼树;并调用 print1()和 p
6、rint2()函数将哈夫曼的存储结构的初态和终态进行输出。然后调用 HuffmanEncoding()函数对哈夫曼树进行编码,调用coding()函数将编码写入文件;再调用 decode()对编码进行译码,再输出至界面。至此,整个工作就完成了。测试数据:例如从文本中读到文章为:IAMASTUDENT。则效果如下:IAMASTUDENT-HuffmanTree 的初态:2 0 0 01 0 0 01 0 0 01 0 0 01 0 0 01 0 0 01 0 0 02 0 0 041 0 0 0- 0 0 0- 0 0 0- 0 0 0- 0 0 0- 0 0 0- 0 0 0- 0 0 0-
7、0 0 0-字符 A 次数:2字符 D 次数:1字符 E 次数:1字符 I 次数:1字符 M 次数:1字符 N 次数:1字符 S 次数:1字符 T 次数:2字符 U 次数:1-HuffmanTree 的终态:2 13 0 01 10 0 01 10 0 01 11 0 01 11 0 01 12 0 01 12 0 02 14 0 01 13 0 02 14 2 32 15 4 52 15 6 73 16 9 14 16 8 104 17 11 127 17 13 1411 0 15 16-译码后的字符串:IAMASTUDENT*Press any key to continue53 系统(项
8、目)设计(1)设计思路及方案本课题是用最优二叉树即哈夫曼树来实现哈夫曼编码译码器的功能。假设每种字符在电文中出现的次数为 Wi,编码长度为 Li,电文中有 n 种字符,则电文编码总长度为(W1*L1)+(W2*L2)+(Wi*Li)。若将此对应到二叉树上,Wi 为叶结点,Li 为根结点到叶结点的路径长度。那么,(W1*L1)+(W2*L2)+(Wi*Li)恰好为二叉树上带权路径长度。因此,设计电文总长最短的二进制前缀编码,就是以 n 种字符出现的频率作权,构造一棵哈夫曼树,此构造过程称为哈夫曼编码。该系统将实现以下几大功能:从硬盘读取字符串,建立哈夫曼树,输出哈夫曼树的存储结构的初态和终态,输
9、出各种字符出现的次数以及哈夫曼编码的译码等。 (2)模块的设计及介绍从硬盘读取字符串fileopen(参数)实现命令;打印输出;建立 HuffmanTree通过三个函数来实现:void select(参数)初始化;for 接受命令;处理命令;6说明:在 ht1k中选择 parent 为 0 且权值最小的两个根结点的算法int jsq(参数)初始化;for接受命令;处理命令; 说明:统计字符串中各种字母的个数以及字符的种类void ChuffmanTree()初始化;for 接受命令;处理命令;输出字符统计情况;说明:构造哈夫曼树输出哈夫曼树的存储结构的初态和终态分别调用 print1()和 p
10、rint2()来实现void print1(参数)初始化;输出初态;7说明:输出哈夫曼树的初态void print2(参数)for输出终态;说明:输出哈夫曼树的终态哈夫曼编码和译码void HuffmanEncoding(参数)定义变量;处理命令;说明:哈夫曼编码char*decode(参数)定义变量;while接受命令;处理命令;说明:哈夫曼译码8(3)主要模块程序流程图下面介绍三个主要的程序模块流程图:主函数流程图:结束统计字符种类及频率字符总数 num建立哈夫曼树哈夫曼编码哈夫曼译码打开文件?开始否是图 3.1流程图注释:该图比较简单,主要是调用各个函数模块,首先代开已经存在的文件,然后
11、统计总的字符数以及出现的各个字符和频率。然后才开始建立哈夫曼树,接着在哈夫曼树的基础上对其进行编码,编码之后才是译码。最后输出结束。9构造哈夫曼树:开始结束第 i 个结点权值i=num?创建哈夫曼树输出字符统计情况第 i 个根结点i=2*num-1?i=num?否是否是否是图 3.2流程图注释:该图是表示构造哈夫曼树的过程。首先输入 num 个叶结点的权值,当 i=num 是循环结束。然后进行哈夫曼树的构建,当 i=2*num-1 是循环结束。最后输出所得到的字符统计情况。10哈夫曼编码:结束开始Tp.lchlid=c?i=Ac=p; /若 tc是 tp的左孩子/则生成 0;否则生成底码str
12、cpy(Hi.bits,Hi.len=num-start;代码解释:对 str 所代表的字符串进行编码并写入文件。将翻译的二进制15码写入文本文件。void coding(HuffmanCode HC ,char *str) int i,j;FILE *fp;fp=fopen(“codefile.txt“,“w“);while(*str)for(i=1;i#include #include #include/*类型相关变量的定义*#define n 100 /叶子结点数#define m 2*n-1 /哈夫曼树中的结点树typedef structchar ch;char bits9; /存放
13、编码位串int len; CodeNode;typedef CodeNode HuffmanCoden+1;typedef struct int weight; /权值int lchild,rchild,parent; /左右孩子几双亲指针 HTNode;typedef HTNode HuffmanTreem+1; /0 号单元不用int num;/*建立 HuffmanTree*void select(HuffmanTree T,int k,int int min1=101;for(i=1;i=A否则生成底码cd-start=(Tp.lchild=c) ? 0 : 1;c=p;strcpy(
14、Hi.bits,Hi.len=num-start;void coding(HuffmanCode HC ,char *str) /对 str 所代表的字符串进行编码 并写入文件int i,j;FILE *fp;fp=fopen(“codefile.txt“,“w“);while(*str)for(i=1;i=stri)HTi.weight=(char)* ;/*打开文本*int fileopen(char string)FILE *fp;if(fp=fopen(“E:数据结构课程设计file1.txt“,“r“)=NULL)printf(“不能打开文件!n“);exit(1);while(fg
15、ets(string,100,fp)!=NULL)printf(“%sn“,string);fclose(fp);return 0;/*主调函数*void main() char string100;char *s,str27;int cnt27;HuffmanTree HT;HuffmanCode HC;printf(“读出文本为:n“);fileopen(string);num=jsq(string,cnt,str); /统计字符的种类及各类字符出现的频率DhuffmanTree(HT,cnt,str);printf(“-n“);printf(“HuffmanTree 的初态:n“);print1(HT);ChuffmanTree(HT,HC,cnt,str); /建立哈夫曼树 26HuffmanEncoding(HT,HC); /生成哈夫曼编码coding(HC,string); /建立电文哈夫曼编码文件printf(“-n“);printf(“HuffmanTree 的终态:n“);print2(HT);s=decode(HC); /读编码文件译码 printf(“译码后的字符串:n“);printf(“%sn“,s); /输出译码后的字符串printf(“*n“);