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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

数据结构实习哈夫曼编码文档格式.docx

1、4本次作业心得 . . . . . . . . . . . . . . . . . . . . 241.题目 设二叉树以二叉链表的形式保存,T为指向根结点的指针。试完成以下功能:1、建立二叉树:从键盘输入各结点的值,可参照二叉树的顺序存储方式。例如输入“a,b,c, ,d”表示结点a是根,b和c是a的两个孩子,b仅有右孩子d。2、统计T中叶结点的个数。3、统计T中度为2的结点的个数。4、求树T的高度。5、判断T中是否有度为1的结点(即按照国外教材的定义,是否为满树)。在此基础上,实现Huffman编码及译码,达到以下两个目标:1、掌握二叉树的二叉链表存贮结构。2、掌握Huffman算法。2.要

2、求使用文件保存初始的文本数据及最终的结果。 文件名为inputfile1.txt的文件保存的是一段英文短文; 文件名为inputfile2.txt的文件保存01形式的编码段; 文件名为outputfile1.txt的文件保存各字符的出现次数和对应的编码; 文件名为outputfile2.txt的文件保存对应于inputfile2.txt的译码结果。统计inputfile1.txt中各字符的出现频率,并据此构造Huffman树,编制Huffman编码;根据已经得到的编码,对01形式的编码段进行译码。具体的要求:1将给定字符文件编码:生成编码,输出每个字符出现的次数和编码;2将给定编码文件译码:生

3、成字符,输出编码及其对应字符。3.程序实现 3.1程序运行及编译环境程序是用Visual Studio 2010即VS10.0 编译的。可以在windows系列的操作系统上运行。 3.2程序描述该程序主要用于实现二叉树的二叉链表保存并实现Huffman编码以及译码。其流程如下: A).程序读取输入文件,并生成相应的数据结构a.用数组来声明并存储树,完成初始化的工作b.读入文本内容,并统计每个字符的频率c.根据每个字母的权重,对森林里每棵树的相应参数重新赋值d.将森林合并为树B).输出相关信息 a.在文本里依次输出字符出现的次数,频率以及编码 B.在控制台输出统计的字母频率(其实这个不是必要的)

4、C).编码以及译码 a.在统计好的字符出现次数的基础上编码 b.编码前的两个文件比较 c.对编码的文件译码 d.译码后的两个文件比较D).完成3.3实现功能3.3.1子功能模块1 读入文本,统计频率。 /开始读入文件 while(fin1.get(c)/读入文件 letc.weight+;/统计每个字符的权重 CharCount+; if(c127) cout打开文件在一以下位置出现错误:; fin1.get(c);fin1.get(c); for(int i=0;iTIPS;i+)fin1.get(c);coutc;的前面 temp_char的后面endl;可能原因有:文本编码为UTF-8,

5、Unicode,Unicode big endian等非ANSI编码; 或者文本含有中文字符或者全角字符endl=a&cAZ) LetterCount+; for(int i=0;i+) temp_chari=temp_chari+1; temp_charTIPS=c; fin1.close();/读入完成3.3.1.1 输入项 输入项有: fin1:文件输入流3.3.1.2输出项letc.weight;/每个字符的出现次数CharCount;/所有字符出现次数总和/文件流读入的每个字符temp_char;/保存当前读到字符的前几个字符,以便于在含有Unicode,UTF-8等编码的字符时,及

6、时找出出错字符位置3.3.1.3数据结构的定义3.3.1.3.1全局数据结构 全局数据结构有:/用一个结构来存储字符,统计的权重,以及该字母在哈夫曼树里面的偏移,这样可以快速定位到该字母的结点typedef struct Let char letter;/字符 int offset;/字母在哈夫曼树里面的偏移 int weight;/字符的权重 double freq;/freq表示在所有字符中的频率 double letterFreq;/表示字母在所有字母中的频率;typedef struct HuffNode/letter表示结点的字符/weight表示权重 HuffNode* left;

7、/左孩子 HuffNode* right;/右孩子 bool merge;/merge表示能否合并,如果两棵树合并后,就不可以合并了 bool codeMAXCODELENGTH;/0表示左边,1表示右边 int ValidCode;/ValidCode表示前多少位的编码是有效的class HuffTree HuffNode* root;/树的根节点public: HuffTree(char letter,int weight); HuffTree(); HuffNode* getRoot(); void setRoot(HuffNode* Root); HuffTree* HuffTreeM

8、erge(HuffTree* Tree1,HuffTree* Tree2); HuffTree* CreateHuffTree(HuffTree HN,int COUNT); void MidOrder(HuffNode* node); void PreOrder(HuffNode* node); void HuffCode(HuffNode* root); 3.3.1.32 局部数据结构 无3.3.1.4算法及程序说明本程序中重要的算法思想是:给出了一种编码的时候不同的遍历方法。把树中所有的结点都对应到一个整数(不同的结点,对应不同的整数),然后按照整数从小到大的顺序,依次找到其结点并且访问

9、,编码。这个对应的关系式这样的:一个整数,例如10,那么它的二进制表示为1010B,于是,把最高位1去掉,剩下的是010B,然后这个010B对应的是从根节点的左子树的右子树的左子树对应的结点,(就是0表示左子树,1表示右子树)并且根据这个二进制数,可以很快的找到这个结点,而且每次都是从根节点开始,没有系统栈的开销。不同的结点,对应不同的整数是显然的,因为从根节点到达不同的结点的次序是不同的,因此这些次序对应的二进制代码也不一样,在其前面加一项1以后,还是不一样的。为此,需要用到一下两个函数作为基础A).本程序最重要的是这几个函数: 1.void Convert2Bin(int num,bool

10、 a,int& idx);把一个十进制数转化为二进制数num:要转化的十进制数;bool a:为节省空间,采用bool型来存储二进制的每一位;idx表示代码如下:void Convert2Bin(int num,bool a,int& idx)/把一个整数num转化为二进制的形式,存放在数组a里面,idx存放输出到数组的哪一项 int i=0; bool temp; while(num1) /除2取余,得到逆序的二进制序列 ai+=num%2; num/=2; ai=num; idx=i; for (int j=0;jright; break; case false:/false时,左走lef

11、t; default: coutletter)/到达一个有字母的结点,这时候就可以得到编码 temp-ValidCode=j; for(int k=0;kValidCode;k+) temp-codek=orderk; break; C).体会 算法并不是什么代码,也不是什么规则,方法只要能用有限的步骤实现相应的功能,这就是一个算法。由于开始时,我死按着常规的顺序去遍历树,想去得到每个节点的编码,发现递归遍历代码容易出错,非递归遍历代码太复杂,以至于我写的每一次遍历都得不到正确结果,所以后来受第一个习题的影响,用了第一个习题里面的思想。 3.3.2子功能模块2 用于实现两棵树合并成一棵新树 T

12、ree1,Tree2,分别表示两棵树指针,返回两棵树合并后形成的一颗新树HuffTree* HuffTreeMerge(HuffTree* Tree1,HuffTree* Tree2) HuffTree* Tree=new HuffTree; if (Tree1-root-merge=false|Tree2-merge=false)/两棵树均不可合并时,给出错误提示 Can not merge into one root! return Tree1; Tree-weight=Tree1-weight+Tree2-weight;/新树的权重是原来两棵树的权重之和merge=true;/新树标记为

13、可以合并 Tree1-merge=false;/原来那两棵树均不可合并 Tree2-left=Tree1-root;/Tree1为左子树right=Tree2-/Tree为右子树 return Tree;3.3.3子功能模块3HuffTree* CreateHuffTree(HuffTree HN,int COUNT);HN表示分立的树;COUNT表示树的棵树,返回形成的那棵哈夫曼树的根;实现方法:先取出可以合并的两棵树,然后往后找,发现权重比那两棵小的就取权重小树 直到最后,然后,两棵树合二为一,合成的新树依次放在原来数组的后面,直到原来 所有的树都合并完毕。 HuffTree* Creat

14、eHuffTree(HuffTree HN,int COUNT)/count表示可以用来合并成为哈夫曼树的结点个数 HuffTree* minTree1; HuffTree* minTree2; HuffTree* temp; int i=0; int count=COUNT; int append=COUNT; while(count1)/还没有合并完毕 for(i=0;2*COUNT-1;i+)/找第一课可以合并的树 if (HN+i)-merge=true&(HN+i)-weight!=0) minTree1=HN+i; i+; break; for(;i+)/找第二课可以合并的树 mi

15、nTree2=HN+i; if (minTree1-weightminTree2-weight)/使得minTree1总是小于minTree2; temp=minTree1; minTree1=minTree2; minTree2=temp; for (;i+)/后面要是有可以合并的权重比之更小的树就取那棵树用于合并 if (HN+i)- weight weight) minTree2=minTree1; minTree1=HN+i; else minTree2-root=HuffTreeMerge(minTree1,minTree2)-/两棵树合并成为一棵树 HNappend+.root=T

16、ree-/新合成的树置于原来数组后面 count-;3.3.4子功能模块4 函数原型:void MidOrder(HuffNode* node); 函数参数:树的根节点 实现方法:递归,中序遍历 代码: void MidOrder(HuffNode* node)/中序递归遍历,并且输出编码 if(node) MidOrder(node-left); if(node-letter) coutletter)weightcodei;right);3.4运行结果A).程序基本功能的实现:图1 控制台输出每个字符的权重以及编码图2 控制台输出每个字符的权重以及编码图3 编码的文件inputfile1.t

17、xt以及解码后的文件outputfile2.txt文件大小均为19KB图4 编码的文件inputfile1.txt图5 解码后的文件outputfile2.txt由于这样的题目比较有意思,而且输入的文本是大学两年来写过的所有英语作文,这些数据是在十几篇英语作文里面的含空格,回车等一切标点的19053个字符,1019个互不相同的单词的数据基础上得出的。所以,除了实现以上功能外,我还特地统计了自己写的作文的一些统计特性,比如每个英文字符在所有英文字符的频率,发现还是e的频率最高,当然了,程序中e和E算作不同的字母。B).附加功能:图6 统计所有字符的频率,如果是英文字符,还算其在所有英文字符这个群体里的频率。这在一定程度上反映了语言的特性,利用一个更加大的更具有普遍性的语料库,可以统计所有字母的频率,有一种古老破解密码的方法就是基于这种大语料库下字符频率的,虽然密文不是严格按照这个频率分布的,但是频率最大的几个字母是不变的,这就为破解密码提供了可能,当然了,现代密码学是建立在数论基础上的公开密钥的方法,密文不再具有统计特性。扯得有点远,其

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

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