完整word版哈夫曼编码译码器实验报告.docx
- 文档编号:5396627
- 上传时间:2022-12-15
- 格式:DOCX
- 页数:23
- 大小:177.71KB
完整word版哈夫曼编码译码器实验报告.docx
《完整word版哈夫曼编码译码器实验报告.docx》由会员分享,可在线阅读,更多相关《完整word版哈夫曼编码译码器实验报告.docx(23页珍藏版)》请在冰豆网上搜索。
完整word版哈夫曼编码译码器实验报告
中北大学
数据结构
课程设计说明书
学生姓名:
郝晨栋
学号:
1021010933
学院:
软件学院
专业:
软件开发与测试
题目:
哈夫曼编码/译码器
指导教师
康珺
2011年12月20日
1问题描述
1.设计一个利用哈夫曼算法的编码和译码系统,重复地显示并处理以下项目,直到选择退出为止。
(1) 将权值数据存放在数据文件(文件名为data.txt,位于当前目录中);
(2) 分别采用动态和静态存储结构;初始化:
键盘输入字符集大小n、n个字符和n个权值,建立哈夫曼树;
(3) 编码:
利用建好的哈夫曼树生成哈夫曼编码;输出编码;
设计要求:
(1)符合课题要求,实现相应功能;
(2)要求界面友好美观,操作方便易行;
(3)注意程序的实用性、安全性。
2需求分析
编写此软件是为了实现一个利用哈夫曼算法的编码和译码系统。
比如,再利用电报进行通讯时,需要将文字转换成由二进制的字符组成的字符串.比如需传送的电文为“ABACCDA”假设将A,B,C,D分别编码为00、01、10、11.则上述电文遍为00010010101100,总长度为14位。
但是在传送过程中,总希望长度能够尽可能的短,于是我们想采用长度不等的编码。
但是这种编码必须遵循:
任何一个字符的编码都不是另一个字符编码的前缀。
对此软件的要求:
能够正确的使得对于输入的字符进行编码以及译码,并且是的在译码过程中不会出错,同时能够将编码以及译码的结果正确的存入文件当中。
3概要设计
3.1抽象数据类型定义
ADTBinaryTree{
数据对象:
D={ai|ai∈ElemSet,i=1,2,...,n,n≥0}
数据关系:
若D为空集,则称为空树。
若D仅为一个数据元素,则R为空集,否则R={H},H是如下的二元关系:
(1)再D中存在唯一的称为根的数据元素root,它在关系H下无前驱。
(2)若D-{root}<>空集,则存在一个划分D1,D2,···,Dm(m〉0)。
(3)对应于D—{root}的划分,H—{〈root,X1},···,〈root,Xm〉}有唯一的一个划分H1,H2,···,Hm(m〉0).
基本操作:
InitTree(&T)
操作结果:
构造空树T.
DestroyTree(&T)
初始条件:
树T已存在.
操作结果:
树T被销毁。
ClearTree(&T)
初始条件:
树T已存在。
操作结果:
将树T清为空栈。
TreeEmpty(T)
初始条件:
树T已存在。
操作结果:
若树T为空,则返回TRUE,否则FALSE。
TreeDepth(T)
初始条件:
树T已存在.
操作结果:
返回T的深度。
Root(T)
初始条件:
树T已存在。
操作结果:
返回树T的根.
3.2总体框图以及功能描述
4详细设计
4.1数据类型的定义
(1)哈夫曼树节点类型
structhufmtreenode{//哈弗曼树结点数据类型
chardata;
floatweight;//结点权值
intparent,lchild,rchild;//父结点,左、右孩子结点
};
(2)哈夫曼树类型
structhufmtree{//哈弗曼树数据类型
hufmtreenode*node;//结点数组(根据n的值动态分配)
intn;//叶子结点数
};
(3)哈夫曼编码数据类型
structCodetype{//哈弗曼编码数据类型
char*bits;//编码流数组,
intstart;//编码实际在编码流数组里的开始位置
}
4.2主要模块的算法描述
(1)主函数:
voidmain()
{
printf(”哈夫曼编码译码系统\n");
tree=CreateHuffmanTreeFromSourceFile();//读取文件建立哈树
tree=CreateHuffmanTreeByInput();//手动输入建立哈夫曼树
HuffmanCode(tree);//打印字符集的哈夫曼编码
tree=Encoding(tree);//对文本文件编码
Decoding(tree);//对代码文件译码
}
(2)构造哈夫曼树
hufmtree*BuildHuffmanTree(hufmtree*tree){//构建叶子结点已初始化的哈夫曼树
For(p=HT,i=1;i<=n;++i,++p,++w)
*p={0,0,0,0};
For(;i<=m;++i,++p)
*p={0,0,0,0);
For(i=n+1;i〈=m;i++)
{
Select(HT,i—1,s1,s2);
HT[s1]。
parent=i;HT[s2].parent=i;
HT[s1].parent=s1;HT[s1].parent=s2;
HT[i]。
weight=HT[s1].weight+HT[s2].weight;
}
}
(3)利用哈夫曼编码算法哈夫曼编码
HuffmanCode(tree){
hc=(HuffmanCode)malloc((n+1*sizeof(char*))
cd=(char*)malloc(n*sizeof(char));
cd[n—1]=”\0”;
for(c=i;i〈=n;++i)
start=n-1;
for(c=i;f=HT[i].parent;f!
=0;c=f,f=HT[f].parent)
If(HT[f]。
lchild==c)cd[--start]=’\0';
HC[i]=(car*)malloc((n—start)*sizeof(char));
Strcpy(HC[i],&cd[start]);
}
5测试分析
(1)打开源文件统计各字符及权值信息并存入data.txt文件中
(2)将统计出的权值信息进行哈夫曼编码
(3)将编码内容存入CodeFile。
txt文件中
(4)将CodeFile.txt文件中的内容译码
(5)成功译码把原字符信息存入DeCodeFile.txt文件中
(6)输入各字符及其权值
(7)将各字符的权值信息进行哈夫曼编码
(7)根据编码再进行译码工作
6课程设计总结
课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。
随着科学技术发展的日新日异,当今计算机应用在生活中可以说得是无处不在。
因此作为二十一世纪的大学来说掌握计算机开发技术是十分重要的。
回顾起此次课程设计,至今我仍感慨颇多,的确,自从拿到题目到完成整个编程,从理论到实践,在整整一个星期的日子里,可以学到很多很多的的东西,同时不仅可以巩固了以前所学过的知识,而且学到了很多在书本上所没有学到过的知识。
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力.在设计的过程中遇到问题,这毕竟独立做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说结构体……通过这次课程设计之后,一定把以前所学过的知识重新温故.
这次课程设计终于顺利完成了,在设计中遇到了很多编程问题,最后在谢老师的辛勤指导下,终于游逆而解。
同时,在李玉蓉老师的《软件工程导论》课上我学得到很多实用的知识,在次我表示感谢!
同时,对给过我帮助的所有同学和各位指导老师再次表示忠心的感谢!
附录(源程序清单)
#include〈stdio。
h>
#include〈conio。
h〉
#include h> #defineMAXVAL10000。 0 structhufmtreenode{//哈弗曼树结点数据类型 chardata; doubleweight;//结点权值 intparent,lchild,rchild;//父结点,左、右孩子结点 }; structhufmtree{//哈弗曼树数据类型 hufmtreenode*node;//结点数组(根据n的值动态分配) intn;//叶子结点数 }; structCodetype{//哈弗曼编码数据类型 char*bits;//编码流数组,n为为哈夫曼树中叶子结点的数目,编码的长度不可能超过n intstart;//编码实际在编码流数组里的开始位置 }; voidSortHufmtree(hufmtree*tree){//将哈夫曼树n个叶子结点由大到小排序 inti,j,k; hufmtreenodetemp; if(tree==NULL) return; for(i=0;i { k=i; for(j=i+1;j if(tree-〉node[j].weight>tree-〉node[k]。 weight) k=j; if(k! =i) { temp=tree->node[i]; tree—〉node[i]=tree—〉node[k]; tree->node[k]=temp; } } } Codetype*HuffmanCode(hufmtree*tree){//哈弗曼编码的生成 inti,j,p,k; Codetype*code; if(tree==NULL) returnNULL; code=(Codetype*)malloc(tree-〉n*sizeof(Codetype)); for(i=0;i〈tree—>n;i++) { printf(”%c",tree->node[i].data);//打印字符信息 code[i].bits=(char*)malloc(tree—〉n*sizeof(char)); code[i]。 start=tree—>n-1; j=i; p=tree-〉node[i]。 parent; while(p! =-1){ if(tree->node[p].lchild==j) code[i]。 bits[code[i]。 start]=’0’; else code[i].bits[code[i].start]='1’; code[i].start-—; j=p; p=tree—>node[p]。 parent; } for(k=code[i]。 start+1;k printf("%c”,code[i]。 bits[k]); printf("\n”); } returncode; } hufmtree*BuildHuffmanTree(hufmtree*tree){//构建叶子结点已初始化的哈夫曼树 //tree中所有叶子结点已初始化 inti,j,p1,p2,m; floatsmall1,small2; m=2*(tree-〉n)-1; for(i=tree—〉n;i〈m;i++)//初始化所有非叶子结点 { tree->node[i].parent=-1; tree—〉node[i]。 lchild=-1; tree—〉node[i]。 rchild=—1; tree—>node[i]。 weight=0。 0; } for(i=tree-〉n;i〈m;i++)//构建哈夫曼树 { small1=small2=MAXVAL; for(j=0;j〈=i-1;j++) { if(tree—>node[j].parent==—1&&tree->node[j].weight<=small1) { small1=tree-〉node[j].weight; p1=j; } } for(j=0;j<=i—1;j++) { if(tree—>node[j]。 parent==—1&&tree—〉node[j]。 weight<=small2&&(j! =p1)) { small2=tree—>node[j].weight; p2=j; } } tree—〉node[p1]。 parent=tree—〉node[p2]。 parent=i; tree—〉node[i]。 weight=tree->node[p1]。 weight+tree—>node[p2].weight; tree->node[i]。 lchild=p1; tree—>node[i].rchild=p2; } returntree; } hufmtree*CreateHuffmanTreeFromSourceFile(){//通过解析源文件建立哈夫曼树 FILE*textfile,*datafile; charch,sourcefilename[100]; inti,j=0,n=0; floatcount[128];//用于统计字符在源文件中出现的次数,27表示26个英文字母和1个空格字符 hufmtree*tree; //打开一个源文件 printf("\n请输入源文件所在路径: \n"); scanf(”%s”,sourcefilename); if((textfile=fopen(sourcefilename,"r"))==NULL){ printf(”\n找不到文件%s\n",sourcefilename); returnNULL; } for(i=0;i<128;i++) count[i]=0; //对源文件中各字符的个数统计 ch=fgetc(textfile); while(! feof(textfile)){ for(i=0;i〈128;i++) if(ch==char(i)){ count[i]++; break; } ch=fgetc(textfile); } //将统计结果写入权值信息文件data.txt中,并构建哈夫曼树 datafile=fopen("f: \\data。 txt”,"w”); for(i=0;i〈128;i++) if(count[i]! =0) n++; fprintf(datafile,”%d\n”,n); tree=(hufmtree*)malloc(sizeof(hufmtree)); tree->node=(hufmtreenode*)malloc((2*n—1)*sizeof(hufmtreenode)); tree—>n=n; printf(”\n源文件的字符集及其权值信息如下: \n"); for(i=0;i〈128;i++) if(count[i]! =0) { //fprintf(datafile,”%c%f\n",char(i),count[i]); fprintf(datafile,"%c%.0f\n",char(i),count[i]); printf(”%c%.0f\n”,char(i),count[i]); tree-〉node[j]。 data=char(i); tree—〉node[j]。 weight=count[i]; tree—>node[j]。 parent=—1; tree-〉node[j].lchild=—1; tree—>node[j]。 rchild=—1; j++; } SortHufmtree(tree); BuildHuffmanTree(tree); fclose(textfile); fclose(datafile); printf("\n哈夫曼树建立完毕,已将权值信息保存至data.txt\n”); returntree; } hufmtree*CreateHuffmanTreeByInput(){//通过用户输入建立哈夫曼树 intn; hufmtree*tree; inti,m; FILE*datafile; tree=(hufmtree*)malloc(sizeof(hufmtree)); datafile=fopen("f: \\data.txt",”w”); //由用户输入字符与权值信息并将其写入data。 txt,同时进行哈夫曼树初始化 printf("请输入字符数: "); scanf(”%d",&n); if(n〈=0) { printf("\n您的输入有误.\n"); returnNULL; } tree—〉node=(hufmtreenode*)malloc((2*n-1)*sizeof(hufmtreenode)); tree-〉n=n; m=2*n-1; for(i=0;i { tree-〉node[i].parent=-1; tree—>node[i].lchild=—1; tree—〉node[i]。 rchild=—1; tree-〉node[i]。 weight=0。 0; } fprintf(datafile,"%d\n”,n); for(i=0;i〈n;i++) { printf("\n输入第%d个字符及其权值: ",i+1); tree—〉node[i].data=getche(); tree—>node[i].weight=getche(); fprintf(datafile,"%c,%.0f\n”,tree-〉node[i].data,tree—〉node[i].weight-48); } fclose(datafile); //哈夫曼树构建 SortHufmtree(tree); BuildHuffmanTree(tree); printf("\n哈夫曼树建立完毕,已将权值信息保存至data.txt\n”); returntree; } hufmtree*CreateHuffmanTreeFromDataFile(){//通过读取权值信息文件建立哈夫曼树 FILE*datafile; inti,n; hufmtree*tree; if((datafile=fopen(”f: \\data。 txt”,”r"))==NULL){ printf(”\n哈夫曼树尚未建立\n”); returnNULL; } //哈夫曼树初始化 fscanf(datafile,"%d”,&n); fgetc(datafile); tree=(hufmtree*)malloc(sizeof(hufmtree)); tree->node=(hufmtreenode*)malloc((2*n—1)*sizeof(hufmtreenode)); tree—〉n=n; for(i=0;i tree-〉node[i].data=fgetc(datafile); fscanf(datafile,”%f\n",&tree-〉node[i]。 weight); tree—〉node[i]。 parent=—1; tree-〉node[i]。 lchild=-1; tree->node[i]。 rchild=—1; } fclose(datafile); //哈夫曼树构建 SortHufmtree(tree); BuildHuffmanTree(tree); returntree; } hufmtree*Encoding(hufmtree*tree){//对源文件进行编码并将其输出至新文件 FILE*textfile,*codefile; charch,sourcefilename[50]; inti,j; Codetype*code; if(tree==NULL)//如果内存中尚未建立哈夫曼树 {//试从data。 txt中读取权值信息并建立哈夫曼树 tree=CreateHuffmanTreeFromDataFile(); if(tree==NULL) returnNULL; } //读取源文件 printf("\n请输入源文件所在路径: \n”); scanf(”%s”,sourcefilename); if((textfile=fopen(sourcefilename,”r”))==NULL){ printf("\n找不到文件%s\n”,sourcefilename); returnNULL; } //打印源文件内容 printf(”\n源文件的原文如下: \n"); ch=fgetc(textfile); while(! feof(textfile)){ printf("%c”,ch); ch=fgetc(textfile); } //编码 printf("\n字符集的哈夫曼编码如下: \n"); code=HuffmanCode(tree); //将源文件中各字符编码并写入codefile codefile=fopen(”f: \\CodeFile.txt",”w"); fseek(textfile,0,SEEK_SET); ch=fgetc(textfile); while(! feof(textfile)) { for(i=0;i〈tree—>n;i++) if(ch==tree->node[i]。 data){ for(j=code[i].start+1;j〈tree->n;j++) fputc(code[i].bits[j],codefile); break; } if(i==tree—>n)//在哈夫曼树树中找不到与文本内容里对应的字符 { printf("\n字符%c不在哈夫曼树中,不能正确编码。 \n",ch); fclose(codefile); returnNULL; } ch=fgetc(textfile);
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 完整 word 版哈夫曼 编码 译码器 实验 报告