ImageVerifierCode 换一换
格式:DOCX , 页数:32 ,大小:209.74KB ,
资源ID:27276794      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/27276794.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(说明书2.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

说明书2.docx

1、说明书2摘 要 随着计算机的普遍应用与日益发展,其应用早已不局限于简单的数值运算,而涉及到问题的分析、数据结构框架的设计以及设计最短路线等复杂的非数值处理和操作。算法与数据结构的学习就是为以后利用计算机资源高效地开发非数值处理的计算机程序打下坚实的理论、方法和技术基础。 算法与数据结构旨在分析研究计算机加工的数据对象的特性,以便选择适当的数据结构和存储结构,从而使建立在其上的解决问题的算法达到最优。 数据结构是在整个计算机科学与技术领域上广泛被使用的术语。它用来反映一个数据的内部构成,即一个数据由那些成分数据构成,以什么方式构成,呈什么结构。数据结构有逻辑上的数据结构和物理上的数据结构之分。逻

2、辑上的数据结构反映成分数据之间的逻辑关系,而物理上的数据结构反映成分数据在计算机内部的存储安排。数据结构是数据存在的形式。数据结构主要介绍一些最常用的数据结构,阐明各种数据结构内在的逻辑关系,讨论其在计算机中的存储表示,以及在其上进行各种运算时的实现算法,并对算法的效率进行简单的分析和讨论。数据结构是介于数学、计算机软件和计算机硬件之间的一门计算机专业的核心课程,它是计算机程序设计、数据库、操作系统、编译原理及人工智能等的重要基础,广泛的应用于信息学、系统工程等各种领域。 学习数据结构是为了将实际问题中所涉及的对象在计算机中表示出来并对它们进行处理。通过课程设计可以提高学生的思维能力,促进学生

3、的综合应用能力和专业素质的提高。关键词:哈夫曼;二叉树;字符;二进制编码目 录1绪论12采用类C语言定义相关的数据类型23各模块的伪码算法3 3.1哈夫曼树的存储结构 3 3.2哈弗曼树的算法3 3.3哈弗曼编码 4 3.4哈弗曼译码 6 3.5主函数 7 3.6显示部分源程序 74函数的调用关系图95调试分析10 5.1调试中遇到的问题及对问题的结决办法 10 5.2算法的时间复杂度和空间复杂度116测试结果12 6.1显示菜单 12 6.2显示编码 13 6.3进行编码 14 6.3进行译码 157设计总结 16参考文献17致谢18附录191绪论在科技飞速发展的今天,信息传输显得尤为重要,

4、这主要体现在计算机之间的数据传输,主要包括文字,声音,图像,视频等文件的传输,而计算机不能直接处理这些信息,计算机只能识别二进制数据。例如文字,在数据通讯中,传送方要将传送的文字转换成由二进制字符0、1组成的二进制串,而接受方要将二进制字符0、1组成的二进制串还原成对应的文字形式。于是便完成了文字数据的传输过程。时下,数据结构是一门随着计算机科学的发展而逐渐形成的新兴学科。随着计算机技术的发展,计算机的应用领域从最初的科学计算发展到人类社会的各个领域,计算机处理的对象也由纯粹的数值发展到字符、表格、图像和声音等各种具有一定结构的数据,这就给程序设计带来一些新的问题。与飞速发展的计算机硬件相比,

5、计算机软件的发展相对缓慢。研究数据结构可以解决计算机之间的数据传输效率低下的问题。在数据结构中,研究树形结构对数据编码有很大作用,对数据构造二叉树编码应用广泛。例如对字符进行传输时,可以设计编码二叉树对字符进行二进制编码转换成二进制数据后再进行传输。哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。哈夫曼压缩属于可变代码长度算法一族。意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。2采用类C语言定义相关的数据类型2.1内部数据类型 char data; /结点值,用字符类型表示

6、int weight; /权值 int parent; /双亲结点 int lchild; /左孩子结点int rchild; 2.2自定义的数据类型typedef struct3各模块的伪码算法3.1哈夫曼树的存储结构 #define N 50 / 叶子结点数 #define M 2*N-1 / 哈夫曼树中结点总数 typedef struct int weight; / 叶子结点的权值 int lchild, rchild, parent; / 左右孩子及双亲指针 HTNode; / 树中结点类型 typedef HTNode HuffmanTreeM+1; 3.2哈弗曼树的算法void

7、CreateHT(HTNode ht,int n) /调用输入的数组ht,和节点数n int i,k,lnode,rnode; int min1,min2; for (i=0;i2*n-1;i+) hti.parent=hti.lchild=hti.rchild=-1; /所有结点的相关域置初值-1 for (i=n;i2*n-1;i+) /构造哈夫曼树 min1=min2=32767; /int的范围是-3276832767 lnode=rnode=-1; /lnode和rnode记录最小权值的两个结点位置 for (k=0;k=i-1;k+) if (htk.parent=-1) /只在尚

8、未构造二叉树的结点中查找 if (htk.weightmin1) /若权值小于最小的左节点的权值 min2=min1;rnode=lnode; min1=htk.weight;lnode=k; else if (htk.weightmin2) min2=htk.weight;rnode=k; htlnode.parent=i;htrnode.parent=i; /两个最小节点的父节点是i hti.weight=htlnode.weight+htrnode.weight; /两个最小节点的父节点权值为两个最小节点权值之和 hti.lchild=lnode;hti.rchild=rnode; /父

9、节点的左节点和右节点 3.3哈弗曼编码void CreateHCode(HTNode ht,HCode hcd,int n) int i,f,c; HCode hc; for (i=0;in;i+) /根据哈夫曼树求哈夫曼编码 hc.start=n;c=i; f=hti.parent; while (f!=-1) /循序直到树根结点结束循环 if (htf.lchild=c) /处理左孩子结点 hc.cdhc.start-=0; else /处理右孩子结点 hc.cdhc.start-=1; c=f;f=htf.parent; hc.start+; /start指向哈夫曼编码hc.cd中最开始

10、字符 hcdi=hc; void DispHCode(HTNode ht,HCode hcd,int n) /输出哈夫曼编码的列表 int i,k; printf( 输出哈夫曼编码:n); for (i=0;in;i+) /输出data中的所有数据,即A-Z printf( %c:t,hti.data); for (k=hcdi.start;k=n;k+) /输出所有data中数据的编码 printf(%c,hcdi.cdk); printf(n); void editHCode(HTNode ht,HCode hcd,int n) /编码函数 char stringMAXSIZE; int

11、i,j,k; scanf(%s,string); /把要进行编码的字符串存入string数组中 printf(n输出编码结果:n); for (i=0;stringi!=#;i+) /#为终止标志 for (j=0;jn;j+) if(stringi=htj.data) /循环查找与输入字符相同的编号,相同的就输出这个字符的编码 for (k=hcdj.start;k=n;k+) printf(%c,hcdj.cdk); break; /输出完成后跳出当前for循环 3.4哈弗曼译码void deHCode(HTNode ht,HCode hcd,int n) /译码函数 char codeM

12、AXSIZE; int i,j,l,k,m,x; scanf(%s,code); /把要进行译码的字符串存入code数组中 while(code0!=#) for (i=0;in;i+) m=0; /m为想同编码个数的计数器 for (k=hcdi.start,j=0;k=n;k+,j+) /j为记录所存储这个字符的编码个数 if(codej=hcdi.cdk) /当有相同编码时m值加1 m+; if(m=j) /当输入的字符串与所存储的编码字符串个数相等时则输出这个的data数据 printf(%c,hti.data); for(x=0;codex-1!=#;x+) /把已经使用过的code

13、数组里的字符串删除 codex=codex+j; 3.5主函数void main() int n=26,i; char orz,back,flag=1; char str=A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z; /初始化 int fnum=186,64,13,22,32,103,21,15,47,57,1,2,32,20,57,63,15,1,48,51,80,23,8,18,1,16; /初始化 HTNode htM; /建立结构体 HCode hcdN; /建立结构体 for (i=0;in;i+) /把初始化的数据存入ht

14、结构体中 hti.data=stri; hti.weight=fnumi; while (flag) /菜单函数,当flag为0时跳出循环 3.6显示部分源程序: printf(n); printf( *); printf(n * 1-显示编码 *); printf(n * 2-进行编码 *); printf(n * 3-进行译码 *); printf(n * 4-退出 *n); printf( * *); printf(n); printf( 请输入选择的编号:); scanf(%c,&orz); switch(orz) case a: case A: system(cls); /清屏函数

15、CreateHT(ht,n); CreateHCode(ht,hcd,n); DispHCode(ht,hcd,n); printf(n按任意键返回.); getch(); system(cls); break; case b: case B: system(cls); printf(请输入要进行编码的字符串(以#结束):n); editHCode(ht,hcd,n); printf(n按任意键返回.); getch(); system(cls); break; case c: case C: system(cls); DispHCode(ht,hcd,n); printf(请输入编码(以#结

16、束):n); deHCode(ht,hcd,n); printf(n按任意键返回.); getch(); system(cls); break; case d: case D: flag=0; break; default: system(cls); 4函数的调用关系图 图4.1函数的调用关系图图4.2建立哈夫曼树的算法流程图图4.3构建哈夫曼编码表的算法流程图图4.4编码算法流程图图4.5解码算法流程图5调试分析5.1调试中遇到的问题及对问题的结决办法这部分我主要遇到了如下两个问题,其内容与解决方法如下所列: 第一个问题是权重的筛选部分出现了错误解决办法:一开始对于筛选最小权重的代码编写如下

17、:void SelectMin(HFMT T,int i,int *p1,int *p2) int j, min=999; for(j=0;jTj.weight) min=Tj.weight; *p1=j; min=999; for(j=0;jTj.weight&j!=(*p1) min=Tj.weight; *p2=j; 因为权重中最大的就是字符e的权重103,所以为初始值min赋值时觉得999就已经是无限大了。但是后来发现编码不知确,就开始思考是什么问题。发现每次筛选都将会把最小的两个权重进行相加,所以很快就会超过999,编码自然就出现了问题。所以后来将min定义成了long型,并赋值99

18、9999,问题就解决了。 第二个问题是生成编码表的时候如何将逆向编码正向存储解决办法: 对于求编码的时候,由于是从叶子节点向根顺次而求,所以编码结果将是逆向的。一开始想到的办法是利用栈的结构,将编码依次存入栈中,再在一个字符编码结束时将栈倒空,这样就可以将编码正向存储了。但是又在考虑如果不用栈时候也可以做到。 后来想到了strcpy函数对字符数组进行链接。所以就可以定义一个数组,从后向前存储编码,再在一个字符编码结束时将这个数组有值的重新存入新数组中,即可以成为正向编码了。最终实现编码如下:HFCode hfEn(HFMT T) int i,f,c,start; HFCode hc; char

19、 *cd; hc=(char *)malloc(N+1)*sizeof(char*); cd=(char)malloc(N*sizeof(char); cdN-1=0; for(i=0;iN;i+) start=N-1; for(c=i,f=Ti.parent;f!=-1;c=f,f=Tf.parent) if(Tf.left=c) cd-start=0; else cd-start=1; hci=(char *)malloc(N-start)*sizeof(char); strcpy(hci,&cdstart); return hc; 5.2算法的时间复杂度和空间复杂度 在统计字符出现频率的

20、算法中,是一个二重循环,时间复杂度为O(len*len),len是字符串的长度。 在构造哈夫曼树的算法中,需要找出没有扩展过且当前最小的两个节点组成新节点,这里需要遍历的时间复杂度为O(n*n),n为叶子节点的个数。最后对输入字符串编码的时间复杂度为O(len*n),因为对每一个字符都需要查找一次哈夫曼编码表。 数据结构采用了一维数组hnode2n-1来存储n个叶子节点形成的哈夫曼树,空间复杂度为O(n);同时利用了一个hcn*n的二维数组来存储每个叶子节点对应的哈夫曼编码表,空间复杂度为O(n*n)。6测试结果6.1显示菜单6.2.显示编码6.3.进行编码6.4.进行译码7设计总结本次课程设

21、计涵盖了对字符及其使用频度构造哈夫曼树和哈夫曼编码表,再对输入字符进行哈夫曼编码,将编码写入文件进而读取文件并译码等模块功能,整个过程将结构体、指针、数组、语句循环选择结构,链表,文件读写等知识联系在一起,考察了我们运用C+语言的能力以及对数据结构的理解,通过几天的编写和调试,基本上实现了数据传输的过程。而在这个过程中,我开始进展十分缓慢,主要是因为首次接触有关程序实现编码的问题,对树形结构也不怎么了解,于是在第一步构造哈夫曼树的时候就花了很长时间来理解哈夫曼算法,哈夫曼树构造函数里面设置了很多变量,那个核心部分怎么也看不懂,我带着疑惑地将代码全都打出来,运行成功后我对着结果一步一步列出其中的

22、过程,在循环中确定每一次各变量的值,对照着事先画好的哈夫曼树仔细看了看,终于了解了各变量的作用,哈夫曼树构造的原理大致也就清楚了,于是后面的哈夫曼编码表结构,哈夫曼译码过程也迎刃而解,整个过程的原理就把握住了。 在上机调试的时候,也屡次出行过错误,例如对字符进行哈夫曼编码的时候,是从哈夫曼树的根结点开始沿父亲链往上回溯的,于是这样得到的编码实际上是反过来的,但用来存储它们的位串数组也不一般,在编码表结构里还定义了一个位置变量start,用以指示哈夫曼编码在数组中的起始位置,start是从最后一个开始指向的,即从后面开始存储二进制编码,于是从前面开始读取就能获得字符的哈夫曼编码。通过这样不断的调

23、试,我对整个结构的理解就越来越清楚,经过几天的努力,一个小型的哈夫曼编译码系统就完成了。整个系统能实现对任意输入的空格或26个大写英文字符进行哈弗曼编码,再写入文件,最后读取文件并译码的功能。但仍有很多方面做的还存在缺陷,例如系统能翻译出的二进制位数不能大于1000,不能输入过多的字符,还有在程序界面也没怎么规划,今后还将努力改善。参考文献1 张俊、张彦铎C+面向对象程序设计北京:中国铁道出版社,20082 田鲁怀数据结构北京:电子工业出版社,20063 唐策善,黄秋生数据结构北京:中国科技大学出版社,19924 黄杨铭数据结构北京:科学出版社,20015 徐孝凯数据结构实用教程(C/C+描述

24、)北京:清华大学出版社,19996 黄秋生数据结构北京:经济科学出版社,19997 徐士良使用数据结构北京:清华大学出版社,20008 李春葆数据结构考研辅导书北京:清华大学出版社,20039 李春葆数据结构习题解析(C语言版)北京:清华大学出版社,2000致 谢在此次课程设计中,我们衷心感谢贾老师对我们的细心指导。贾老师指引我们的课程设计的写作的方向和架构,并指正出其中误谬之处,使我们一起努力完成, 贾老师要指导很多同学的论文,加上本来就有的教学任务,工作量之大可想而知,老师的用心良苦。在此,谨向贾老师衷心的感谢! 谢谢贾老师在我们的课程设计过程中给与我们的极大地帮助。同时,课程设计的顺利完

25、成,离不开小组内部成员的互相努力,团结协作。在整个的课程设计写作中,大家互相支持,努力需找问题答案所在。最终顺利完成了这个课程设计。在文档的写作过程中也学到了做任何事情所要有的态度和心态,首先做学问要一丝不苟,对于发展过程中出现的任何问题和偏差都不要轻视,要通过正确的途径去解决,在做事情的过程中要有耐心和毅力,不要一遇到困难就达退堂鼓,只要坚持下去就可以找到思路去解决问题的。而且要学会与人合作,这样做起事情来就可以事半功倍。附录#include #include /要用system函数要调用的头文件#include /用getch()要调用的头文件#include #define N 50 /义用N表示50叶节点数#define M 2*N-1 /用M表示节点总数 当叶节点数位n时总节点数为2n-1#define MAXSIZE 100typedef struct char data; /结点值 int weight; /权值 int parent; /双亲结点 int lchild; /左孩子结点 int rchild; /右孩子结点HTNode; typedef struct char cdN; /存放哈夫曼码 int start; /

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1