《数据结构课程设计哈夫曼编码译码器共13页文档.doc》由会员分享,可在线阅读,更多相关《数据结构课程设计哈夫曼编码译码器共13页文档.doc(13页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、如有侵权,请联系网站删除,仅供学习与交流数据结构课程设计哈夫曼编码译码器【精品文档】第 13 页西安郵電學院数据结构课程设计报告题 目1: 哈夫曼编码/译码器 题 目2: 学生信息管理系统 系部名称:通信工程系专业名称:通信工程班 级:*学号:*学生姓名 :*指导教师:*时间:2009年12月16日 至2009年12月25日 题目1.哈夫曼编码/译码器 一、 课程设计目的通过对哈夫曼编码/译码器的实现,熟悉了解Huffman树的创建过程以及存储结构,对Huffman编码/译码过程及原则有了更深层次的认识,锻炼了动手能力,使知识更好的学以致用,为解决数据压缩问题提供方法。二、 课程设计内容通过统
2、计文件中各字符的出现频率,建立Huffman树,再通过建立的已经Huffman的树,对文件中各字符进行编码,将结果存入新的文件中,然后从文件中读取Huffman编码,进行解码,结果存入新的文件中,并与源文件进行比较。三、需求分析1统计字符频率:存文件中读入字符,并对各字符出现频率进行统计;2建立Huffman树:将各字符出现的频率作为权值,建立Huffman树;3Huffman编码:通过已经建立的Huffman树,对个各字符进行编码,并存入新的文件中;4.译码:读取存放Huffman编码的文件,对文件中编码进行译码,把译码结果存入新的文件中;5.结果验证:将译码结果与原文件内容进行比较;四、概
3、要设计1. 系统结构图(功能模块图)开始 main()统计字符频率创建Huffman树对文件编码对编码译码出现次数字符名称初 始 化结点赋值Huffma编码存入文件读取编码存入文件对编码译码对编码译码成功失败2功能模块说明1:统计字符频率: 定义结构体typedef struct str char data; char num;str;其中data域存放字符名称,num域存放字符出现频率,读取文件ywq1.txt,通过循环比较将结果赋入S2128中;2:创建Huffman树: 定义结构体typedef struct char data; int weight; int parent; int
4、lchild; int rchild;HTNode,HuffmanTreeM+1;作为Huffman树存储节点类型,调用CrtHuffmanTree()函数,初始化各节点均为 0;然后将存储字符频率的数组S2的值赋值给各节点,字符出现频率作为权值,创建Huffman树;3:对文件编码: 定义结构体typedef struct char data; char bitsN+1;CodeNode,HuffmanCodeN;作为HuffmanCode的存储类型,调用CrtHuffmanCode()函数,从叶子节点向上回溯,是lchild则赋值0,是rchild则赋值为1,对各字符编码,再调用Write
5、ToFile()函数,将结果写入文件ywq2.txt中;4:对文件译码:读取编码文件ywq2.txt中数据,调用DecodHuffmanCode()函数,从根节点开始,读取1,走向rchild,读取0, 走向lchild,直到叶子节点,将叶子节点data域的值写入文件ywq3.txt中;五、详细设计及运行结果1读文件统计字符频率(read()函数中实现):打开源文件ywq1.txt读文件内的字符,初始化数组s1文件是否结束将字符存入数组S1ch.num+读下一个字符给数组末尾加上结束标志“0”关闭文件是否开始结束源文件ywq1.txt:运行结果:2:创建Huffman树,CrtHuffmanT
6、ree():初始化结构体数组htCrtHuffmanTree()有n棵二叉树n 1选权值最小2个二叉树权值相加得新二叉树n - 1n = 1建立Huffman树结束运行结果:3:Huffman编码,CrtHuffmanCode();CrtHuffmanCode()根cd-start = 0cd-start = 1否LchildRchildcdstart 赋给hci.bits是结束对应字符编码写入文件ywq2.txt运行结果:编码文件ywq2.txt:3:译码,DecodHuffmanCode():DecodHuffmanCode()打开文件ywq2.txt读取字符ch文件结束否否找根节点ch
7、= 0, 找lchild;ch = 1, 找rchild;叶子节点是是保存 ywq3.txt是结束运行结果:文件ywq3.txt:4:结果验证:比较源文件ywq1.txt与译码文件ywq3.txt可知,译码结果与源文件一致。Compare()读取ywq1.txt中的字符,存入s1,并输出,读取ywq3.txt中的字符,存入s2,并输出,sii= =s2i 是i+,i=1ik是编译成功编译失败i=k否结束运行结果:六、调试情况,设计技巧及体会通过本次数据结构-哈夫曼编码的应用-课程设计为期两周的实习,让我对数据结构这门课有了深刻的体会,数据结构是在C语言的基础上建立起来的,它是一个程序的必要条件
8、之一,通过本次实习,也让我真正领略到数据结构在一个程序中占有多么重要的地位,程序=算法+数据结构。不同的程序运用不同的数据结构可以起到事半功倍的作用。在这次实习,我就已经深深体会到数据结构的精彩运用。这次实习的题目是哈夫曼编码的应用,在给定的源文件情况下,要根椐所学的哈夫曼树来建立各字符对应的编码从而达到使字符编码化的目的,又要通过解码使所生成的编码能原封不动地解成原来的文件。在编写程序的过程中,也遇到了许多问题,也更让我体会到了编写程序应该是一步一个脚印得来的,编写一个模块,调试一个,不能全部编写的差不多了,在进行调试,这样反而是得不偿失,遇到一大堆的错误让人无从找起。从最开始的统计,建树,
9、选择最小次小值,到后来的编码、译码,自己写了一些,也参考了一下别人好的程序,例如在选择最小值和次小值时,按照书上是给min1和min2初始赋值为32767,但参照了一些好的程序之后,我选择将min1,min2初始赋值位一个小于等于零的数,这样会更好,因为字符的频率不吭能为一个小于等于零的数,如此更符合逻辑;又如统计字符频率时利用ASC码进行统计会更加方便与明了。当我们写一段程序前,一定要反复的思考,怎样写更方便,更完美,这样才能写出一个好的程序来。另外调试程序前要有一个大概的图样,这样在编程时可以有目的,针对性的建立函数,对函数的形参与实参也要在大脑中有个清晰的认识,否则问题出在这就很难解决了
10、。由于哈夫曼编码中会运用到很多循环,所以在编写循环时一定要注意控制语句,防止造成死循环。七、参考文献C语言程序设计-科学出版社数据结构(C语言描述)-清华大学出版社数据结构(使用C语言)-电子科技大学出版社八、附录:源代码#include stdio.h#include string.h#include stdlib.h#include conio.h#define N 100#define M 2*N-1typedef struct /定义哈夫曼树存储节点结构体类型 char data; int weight; int parent; int lchild; int rchild;Huffm
11、anTreeM; typedef struct /定义哈夫曼编码结构体类型 char data; char bitsN;HuffmanCodeN;typedef struct str /定义字符串存储单元结构体类型 char data; char num;str;int read(str s2) FILE *fp; char ch; int i,k; str s1128;for(i=0;i=128;i+) s1i.num = 0; s1i.data = 0; s2i.num = 0; s2i.data = 0; if(fp=fopen(d:ywqywq1.txt,r)=NULL) printf
12、(n库文件不存在!); exit(1); printf(n.读取字符串为:n); ch=fgetc(fp); while(!feof(fp) /统计字符频率 printf(%c,ch); s1ch.num+; s1ch.data = ch; ch=fgetc(fp); fclose(fp); for(i=1,k=1;i=128;i+) if(s1i.num!=0) s2k.num = s1i.num; s2k.data = s1i.data; k+; printf(nn.统计结果为(字符 频率):n); for(i=1;ik;i+) printf( ,s2i.data,s2i.num); pr
13、intf( (共%d种字符)n,k-1); return k;void SelectMin(HuffmanTree ht,int i,int *p1,int *p2) /查找哈夫曼链表中两个权值最小的节点 int j,min1,min2; min1 = min2 = -1; for(j = 1;j=i;j+) if(htj.parent = 0) if(htj.weightmin1|min1=-1) if(min1!=-1) min2 = min1;*p2=*p1; min1 = htj.weight;*p1=j; else if(htj.weightmin2|min2=-1) min2 =
14、htj.weight; *p2=j;void CrtHuffmanTree(HuffmanTree ht,str s,int n) /创建哈夫曼树 int i,m,p1,p2; for(i=1;in;i+) /初始化节点 hti.data = si.data; hti.weight = si.num; hti.parent = 0; hti.lchild = 0; hti.rchild = 0; m=2*n-3; for(i=n;i=m;i+) hti.data = 0; hti.weight = 0; hti.parent = 0; hti.lchild = 0; hti.rchild =
15、0; for(i=n;i=m;i+) SelectMin(ht,i-1,&p1,&p2); /调用SelectMin函数 hti.weight=htp1.weight+htp2.weight; htp1.parent=i;htp2.parent=i; hti.lchild=p1;hti.rchild=p2;void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int k) /利用建立好的哈夫曼树对字符串进行编码 int c,p,i; char cdN+1; int start; for(i=1;ik;i+) hci.data = hti.data;
16、 start = k-1; cdstart = 0; c=i; while(p=htc.parent)!=NULL) cd-start = (htp.lchild=c)?0:1; /左分支为0,右分支为1 c=p; strcpy(hci.bits,&cdstart); printf(nn.每个字符对应的编码为:n); for(i=1;ik;i+) printf( n,i,hci.data,hci.bits);void WriteToFile(HuffmanCode hc,int n) /将编码结果存储在文件文件ywq2.txt中 FILE *fp1,*fp2; char ch; int i;
17、if(fp1=fopen(d:ywqywq1.txt,r)=NULL) printf(n文件不存在!); exit(1); if(fp2=fopen(d:ywqywq2.txt,w)=NULL) printf(n文件不存在!); exit(1); ch = fgetc(fp1);printf(n.编码结果为:); while(ch != EOF) for(i=1;in;i+) if(ch = hci.data) fputs(hci.bits,fp2); printf(%s,hci.bits); ch = fgetc(fp1);fclose(fp1); fclose(fp2);printf(n)
18、;void DecodHuffmanCode(HuffmanTree ht,int n) /码结果进行译码,并将结果存储 在文件ywq3中 FILE *fp1,*fp2; char ch; int p,k; if(fp1=fopen(d:ywqywq2.txt,r)=NULL) printf(n文件不存在!); exit(1); if(fp2=fopen(d:ywqywq3.txt,w)=NULL) printf(n文件未能创建!); exit(1); p=k=2*n-3; ch=fgetc(fp1); printf(.译码为: );while(ch!=EOF) if(ch=0)p=htp.l
19、child; else if(ch=1) p=htp.rchild; if(htp.data!=0) printf(%c,htp.data); fputc(htp.data,fp2); p=k; ch = fgetc(fp1);printf(n);fclose(fp1); fclose(fp2);void compare(int k)FILE *fp1,*fp2; char s1N,s2N;int i=1,j=1;printf(nn.编译前后结果的比较:);if(fp1=fopen(d:ywqywq1.txt,rt)=NULL) printf(n打开文件失败!n); exit(1);print
20、f(nn原文件ywq1.txt中的字符为: ); for(i=1;(s1i=fgetc(fp1)!=EOF;i+)printf(%c,s1i);fclose(fp1); if(fp2=fopen(d:ywqywq3.txt,rt)=NULL) printf(n打开文件失败!n); exit(1); printf(n文 件ywq3.txt中的字符为: ); for(i=1;(s2i=fgetc(fp2)!=EOF;i+)printf(%c,s2i);fclose(fp2); while(jk)if(s1j=s2j) j+;else printf(n编码失败!n); break;if(j=k) p
21、rintf(n前后数据一致,编码成功!。O(_)O。 ! n);void main() int i,k;int j=1;HuffmanTree ht; HuffmanCode hc; str s2128; system(color F5);printf(n-哈夫曼编码译码器-);k=read(s2);getch();CrtHuffmanTree(ht,s2,k); CrtHuffmanCode(ht,hc,k); WriteToFile(hc,k);getch();printf(nn); printf(.建立的哈夫曼树为:); printf(nnumbertdatatweighttlchildtrchildtparent ); for(i=1;ik;i+) printf(n%d : %c %d %d %d %d,i,hti.data,hti.weight,hti.lchild,hti.rchild,hti.parent) ; printf(nn);DecodHuffmanCode(ht,k);getch();compare(k);printf(nn按任意键退出.n);