版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、-计算机学院信管专业数据构造课程设计题 目: 哈夫曼树的应用 班 级:姓 名:学 号:同组人:起迄日期:课程设计地点:指导教师:评阅意见:成绩评定:评阅人: 日期:完成日期:2021年12月目 录一、 需求分析3二、 概要设计4三、 详细设计6四、 调试分析和测试结果7五、 心得体会和总结 10六、 参考文献 10七、 附录 11一、 需求分析一实验要求要求用到数据构造课上学到的线性表的知识,所以就要充分而清晰的理解关于线性表的知识。要现的根本功能很简单,只有删除和插入,增加功能也不过是加上修改。这些在数据构造课上已经讲过,只要能够理解关于线性表的几个相关的根本算法就可以了。问题是将输入的信息
2、保存入文件和从文件输出。这里根本是自学的容,而且要考虑到是否要自行选择保存的磁盘。综上,做这个课题,要具备的知识就是线性表的根本算法,文件的保存和读取算法,必要的C或者C+知识本次我将使用C+实现,以及丰富的程序调适经历。二实验任务一个完整的系统应具有以下功能:功能1从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树并将它存于文件hfmTree中.将已在存中的哈夫曼树以直观的方式比方树显示在终端上;功能2利用已经建好的哈夫曼树如不在存,则从文件htmTree中读入,对文件ToBeTran中的正文进展编码,然后将结果存入文件CodeFile中,并输出结果,将文件CodeFile以紧凑格
3、式先是在终端上,每行50个代码。同时将此字符形式的编码文件写入文件CodePrint中。功能3利用已建好的哈夫曼树将文件CodeFile中的代码进展译码,结果存入文件Te*tFile中,并输出结果。三实验步骤分步实施:1) 初步完成总体设计,搭好框架,确定人机对话的界面,确定函数个数;2) 完成最低要求:完成功能1;3) 进一步要求:完成功能2和3。有兴趣的同学可以自己扩大系统功能。要 求 :1界面友好,函数功能要划分好2) 总体设计应画一流程图3) 程序要加必要的注释4) 要提供程序测试方案5程序一定要经得起测试,宁可功能少一些,也要能运行起来,不能运行的程序是没有价值的。二、概要设计一 设
4、计思想哈夫曼树用邻接矩阵作为存储构造,借助静态链表来实现遍历。二 函数间的关系如下图:主函数显示表头初始化树输入字符编码译码打印编码打印哈夫曼树选最小两个权值Select()三数据构造与算法设计哈夫曼编译码器的主要功能是先建立哈夫曼树,然后利用建好的哈夫曼树生成哈夫曼编码后进展译码 。在数据通信中,经常需要将传送的文字转换成由二进制字符0、1组成的二进制串,称之为编码。构造一棵哈夫曼树,规定哈夫曼树中的左分之代表0,右分支代表1,则从根节点到每个叶子节点所经过的路径分支组成的0和1的序列便为该节点对应字符的编码,称之为哈夫曼编码。最简单的二进制编码方式是等长编码。假设采用不等长编码,让出现频率
5、高的字符具有较短的编码,让出现频率低的字符具有较长的编码,这样可能缩短传送电文的总长度。哈夫曼树课用于构造使电文的编码总长最短的编码方案。其主要流程图如下列图所示。开场结点数是否大于1将data和权值赋给ht输出根结点和权值调用SELECT函数计算根结点函数父结点为两子结点之和输出两子结点和已构造的结点是否为根结点.左子是否为空.此时编码为0I<2*N?I+编码为1完毕否否否右子是否为空是是否否是是是哈夫曼树编译码器流程图三、详细设计功能函数模块划分void main()void printhead()void printree(HuffmanTree HT,int w) /打印赫夫曼树
6、void coprint(HuffmanTree start,HuffmanTree HT)/打印代码文件void printcode() /打印代码void decode() /完成译码功能void encode() /完成编码功能void inputcode() void init()void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n)void select(HuffmanTree t,int i,int &s1,int &s2)int min(HuffmanTree t,int i
7、)/找两个最小的权值1哈夫曼编码:首先定义函数,找出全部权值中最小的两个,然后定义一个变量,使他始终成为最小的那个。再将两个函数最为叶子结点,并得到一个父亲节点,此父亲节点的权值为其叶子节点的权值之和。并将此父亲节点的权值与其余权值进展比拟,重新选出两个最小的权值,再进展上述步骤,直到所有权值形成了一颗二叉树,而此二叉树就是我们所说的最优二叉树,即哈夫曼树。以上为哈夫曼树的建立过程,下面为哈夫曼编码的过程,从叶子节点出发,假设此叶子节点为其父亲节点的左孩子,则将其编码为0,假设为右孩子,则将其编码为1,然后为其父亲节点编码,假设为祖先的左孩子,则变为0,为右孩子则为1,依次向上一层进展遍历,直
8、到遍历到根节点,停顿编码。2译码:对于已经建好的哈夫曼树,要对其进展译码,首先从根出发如果编码为0,则往左孩子遍历,如果编码为1,则往右孩子遍历,直到遍历到叶子节点,便求得该子串相应的字符。3初始化哈夫曼链表:首先输入结点个数,再将字符及权值输入,调用编码函数,得到每个字符编码并将其输出。最后将哈夫曼编码写入文件。4完成编码功能:翻开目录下文件tobetran.t*t,读取里面的字符,对其进展编码后,将编码写入目录下的codefile.t*t中。5完成译码功能:翻开根目录下codefile.t*t文件,读取里面的编码,对其中的编码进展译码,并将得到的容写入根目录下的文件t*tfile.t*t中
9、。6打印编码7打印哈夫曼树四、调试分析和测试结果一初始化哈夫曼链表二编码字符三编码四译码五打印编码六打印哈夫曼函数五、心得体会与总结对于本次课程设计,主要是需要掌握哈夫曼树建立、哈夫曼编码以及哈夫曼译码的算法。并能将其熟练应用于编译码器的完成。经过这次的课程设计,使我们更加了解了数据构造,也更深入地了解了哈夫曼编码与译码算法,课程设计的题目比我们平常的实验容要难,完成它不仅需要有厚实的语言根底,而且还要熟练掌握哈夫曼编码与译码的算法,另外对于文件的根本操作也需要熟悉。通过数据构造课程设计,我的C+语言水平有了比拟大的提高其中。C+语言关于类的操作理解的比以前深刻不少。另外是数据构造方面的提高对
10、哈夫曼树的构造及哈夫曼码方面也有不少的提高。 在工程中也出现了很多的问题,最大的问题就是对程序设计框架构造的不了解,在实现代码与功能的连接时经常会出现各种不同的错误,在实现一些功能时系统常常会报错。许多错误不知从哪修改以致拖了整个设计的后腿。课程设计中,既回忆了很多以前的东西,也发现了很多的问题以前都没遇见过的,收获很大。 通过本次数据构造的课程设计,我学习了很多在上课没懂的知识,并对求哈夫曼树及哈夫曼编码/译码的算法有了更加深刻的了解,更稳固了课堂中学习有关于哈夫曼编码的知识。 此次哈夫曼树的应用系统的设计让自己对数据构造的了解更深入。六、参考文献?C+面向对象程序设计教程?第三版 维兴 林
11、小茶编著 清华大学?数据构造?C语言版严蔚民 吴伟民编著 清华大学六、附录源程序:*include <iostream.h>*include <iomanip.h>*include <string.h>*include <malloc.h>*include <stdio.h>const int UINT_MA*=1000;typedef struct /哈夫曼树的存储表示 int weight; /权值int parent,lchild,rchild; /父节点,左孩子结点,右孩子结点HTNode,* HuffmanTree; /动态
12、分配数组存储哈夫曼树typedef char *HuffmanCode;/动态分配数组存储哈夫曼编码表/-全局变量-HuffmanTree HT; /代表哈夫曼树HuffmanCode HC; /代表哈夫曼编码int *w,i,j,n; char *z;int flag=0; int numb=0;/ -求哈夫曼编码-void line()/画分割线的函数cout<<"n-n"int min(HuffmanTree t,int i)/找两个最小的权值 int j,flag;int k=UINT_MA*; / 取k为不小于可能的值for(j=1;j<=i;j
13、+)if(tj.weight<k&&tj.parent=0)k=tj.weight,flag=j; tflag.parent=1; return flag; /返回标识符/-使s1成为最小权值-void select(HuffmanTree t,int i,int &s1,int &s2) int j;s1=min(t,i);s2=min(t,i);if(s1>s2)/ s1为最小的两个值中序号较小的那个j=s1;s1=s2;s2=j;void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC
14、,int *w,int n)int m,i,s1,s2,start;int c,f;HuffmanTree p;char *cd;if(n<=1)return;m=2*n-1;/申请2n-1个存单元HT=(HuffmanTree)malloc(m+1)*sizeof(HTNode); / 0号单元未用for(p=HT+1,i=1;i<=n;+i,+p,+w)p->weight=*w;/赋权值p->parent=0;p->lchild=0;p->rchild=0;for(;i<=m;+i,+p)/初始化 p->parent=0; for(i=n+1
15、;i<=m;+i) / 建哈夫曼树 select(HT,i-1,s1,s2);/调用建子树的函数HTs1.parent=HTs2.parent=i;/i是s1和s2的父节点HTi.lchild=s1;HTi.rchild=s2;/s1和s2是i的儿子节点HTi.weight=HTs1.weight+HTs2.weight;/i的权值为s1和s2的和HC=(HuffmanCode)malloc(n+1)*sizeof(char*);/分配n个字符编码的头指针向量cd=(char*)malloc(n*sizeof(char); /分配求编码的工作空间cdn-1='0' /编码
16、完毕符for(i=1;i<=n;i+)/逐个字符求哈夫曼编码start=n-1; /编码完毕符位置for(c=i,f=HTi.parent;f!=0;c=f,f=HTf.parent) / 从叶子到根逆向求编码if(HTf.lchild=c)cd-start='0'elsecd-start='1'HCi=(char*)malloc(n-start)*sizeof(char);/为第i个字符编码分配空间strcpy(HCi,&cdstart); /从cd复制编码串到HCfree(cd);/释放工作空间/-初始化哈夫曼链表-void init() fl
17、ag=1;int num;int num2;cout<<"下面初始化哈夫曼链表"<<endl<<"请输入结点的个数n:"cin>>num;/输入结点个数n=num;w=(int*)malloc(n*sizeof(int);/权值z=(char*)malloc(n*sizeof(char);/字符cout<<"n请依次输入"<<n<<"个字符(字符型)n注意:必须以回车完毕:"<<endl;char temp2;for(i
18、=0;i<n;i+)/输入字符 cout<<"第"<<i+1<<"个字符:"<<endl; gets(temp); *(z+i)=*temp;line();for(i=0;i<=n-1;i+)/输出字符cout<<setw(6)<<*(z+i);line();cout<<"n请依次输入"<<n<<"个权值(n注意:必须以回车完毕):"<<endl;for(i=0;i<=n-1;i
19、+)/输入权值cout<<endl<<"第"<<i+1<<"个字符的权值:"cin>>num2;*(w+i)=num2;HuffmanCoding(HT,HC,w,n);/调用哈夫曼编码/-打印编码-cout<<"字符对应的编码为:"<<endl;for(i=1;i<=n;i+)/输出所有编码puts(HCi);/-将哈夫曼编码写入文件-cout<<"下面将赫夫曼编码写入文件"<<endl;FILE *
20、htmTree;char r=' ','0' if(htmTree=fopen("htmTree.t*t","w")=NULL)cout<<"文件翻开失败"<<endl;return;fputs(z,htmTree);for(i=0;i<n+1;i+)fprintf(htmTree,"%6d",*(w+i);fputs(r,htmTree);for(i=1;i<=n;i+)fputs(HCi,htmTree);fputs(r,htmTree);fc
21、lose(htmTree);cout<<"已将字符与对应编码写入根目录下文件htmTree.t*t中"<<endl<<endl;/init/-获取字符并写入文件-void inputcode() FILE *virttran,*tobetran;char str100;if(tobetran=fopen("tobetran.t*t","w")=NULL)cout<<"不能翻开文件"<<endl;return;cout<<"请输入你想要
22、编码的字符"<<endl;gets(str);fputs(str,tobetran);cout<<"获取字符成功"<<endl;fclose(tobetran);/-void encode() /完成编码功能cout<<"下面对目录下文件tobetran.t*t中的字符进展编码"<<endl;FILE *tobetran,*codefile;if(tobetran=fopen("tobetran.t*t","rb")=NULL)cout<&
23、lt;"不能翻开文件"<<endl;if(codefile=fopen("codefile.t*t","wb")=NULL)cout<<"不能翻开文件"<<endl;char *tran;i=99;tran=(char*)malloc(100*sizeof(char); /为tran分配100个字节while(i=99)if(fgets(tran,100,tobetran)=NULL)cout<<"不能翻开文件"<<endl;break
24、;for(i=0;*(tran+i)!='0'i+)for(j=0;j<=n;j+)if(*(z+j-1)=*(tran+i)fputs(HCj,codefile);puts(HCj);if(j>n)cout<<"字符错误,无法编码!"<<endl;break;cout<<"编码工作完成"<<endl<<"编码写入目录下的codefile.t*t中"<<endl<<endl;fclose(tobetran);fclose(c
25、odefile);free(tran);/-void decode() /完成译码功能cout<<"下面对根目录下文件codefile.t*t中的字符进展译码"<<endl;FILE *codef,*t*tfile;if(t*tfile=fopen("Te*tfile.t*t","w")=NULL)cout<<"不能翻开文件"<<endl;if (codef=fopen("codefile.t*t","r")=NULL)cout
26、<<"不能翻开文件"<<endl;char *tbdc,*oute*t,i2;int io=0,i,m;unsigned long length=10000;tbdc=(char*)malloc(length*sizeof(char); /分配空间fgets(tbdc,length,codef);oute*t=(char*)malloc(length*sizeof(char); /分配空间m=2*n-1;for(i=0;*(tbdc+i)!='0'i+) /进入循环i2=*(tbdc+i);if(HTm.lchild=0) *(out
27、e*t+io)=*(z+m-1);io+;m=2*n-1;i-;else if(i2='0') m=HTm.lchild;else if(i2='1') m=HTm.rchild;*(oute*t+io)='0'fputs(oute*t,t*tfile);cout<<"译码完成"<<endl<<"容写入根目录下的文件t*tfile.t*t中"<<endl<<endl;free(tbdc);free(oute*t);fclose(t*tfile);f
28、close(codef);/-void printcode() /打印代码cout<<"下面打印根目录下文件CodePrin.t*t中编码字符"<<endl<<"-n"FILE * CodePrin,* codefile;if(CodePrin=fopen("CodePrin.t*t","w")=NULL)cout<<"不能翻开文件"<<endl;return;if(codefile=fopen("codefile.t*t&q
29、uot;,"r")=NULL)cout<<"不能翻开文件"<<endl;return;char *work3;work3=(char*)malloc(51*sizeof(char);doif(fgets(work3,51,codefile)=NULL)cout<<"不能读取文件"<<endl;break;fputs(work3,CodePrin);puts(work3);while(strlen(work3)=50);free(work3);cout<<"打印工作完
30、毕"<<endl<<endl;fclose(CodePrin); fclose(codefile);void coprint(HuffmanTree start,HuffmanTree HT)/打印代码文件char t=' 'if(start!=HT)FILE * TreePrint;if(TreePrint=fopen("TreePrint.t*t","a")=NULL)cout<<"创立文件失败"<<endl;return; numb+;/该变量为已被声明为
31、全局变量coprint(HT+start->rchild,HT);if(start->lchild!=NULL&&start->rchild!=NULL) t='<'cout<<setw(5*numb)<<start->weight<<t<<endl; fprintf(TreePrint,"%dn",start->weight);coprint(HT+start->lchild,HT);numb-;fclose(TreePrint);void printree(HuffmanTree HT,int w) /打印赫夫曼树HuffmanTree p;p=HT+w;cout<<"下面打印赫夫曼树"<<endl; / 输出"
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年全科医生临床诊疗技术考核试题及答案
- 2026年全国零售药店员工培训考试题及答案
- 摩托车驾考模拟考试科目一试题及答案
- 2026年健康管理学理论知识考核试题及答案
- 2025年吉林省公主岭市高考历史检测卷附参考答案AB卷
- 2026年吉林省和龙市高三历史上册期末考试模拟卷附参考答案【巩固】
- MySQL数据库技术与项目应用教程电子教案 项目六-2 数据库编程(函数和存储过程)
- 2026澳洲银行面试题库及答案
- 2026安泰经济面试题库及答案
- 焊剂烧结熔炼工安全操作测试考核试卷含答案
- 2026年北京市房山区初三下学期二模语文试卷及答案
- 2026山东威海热电集团有限公司招聘44人笔试参考试题及答案解析
- 2026年山西阳泉市县(区)人武部招聘21人易考易错模拟试题(共500题)试卷后附参考答案
- 2026温州医科大学附属第一医院病理科文员招聘1人笔试参考题库及答案解析
- 祛痘护肤品市场分析-魔镜洞察-202604
- 公路雨季施工方案
- 2026年6月大学英语四级考试真题第1套(含答案)
- 基层医疗机构静脉给药服务相关资质核准培训考试试题(附答案)
- 2026春道德与法治三年级下册教学计划及进度表
- 2026广东新高考:语文重点基础知识点
- 6月9日档案宣传日课件
评论
0/150
提交评论