数据结构C语言哈夫曼编码译码Word格式文档下载.docx
- 文档编号:15899244
- 上传时间:2022-11-16
- 格式:DOCX
- 页数:11
- 大小:271.19KB
数据结构C语言哈夫曼编码译码Word格式文档下载.docx
《数据结构C语言哈夫曼编码译码Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《数据结构C语言哈夫曼编码译码Word格式文档下载.docx(11页珍藏版)》请在冰豆网上搜索。
日期:
2013年7月3日
桂林电子科技大学信息科技学院
一、设计思想
要完成哈夫曼的编码和解码需要第一成立哈夫曼树,以后对所有字符按照权重进行编码,最后再对文件内容进行编码和解码。
成立哈夫曼树的思想。
第一概念适合哈夫曼树的节点类型,需要概念的有当前节点的字符,当前节点的左子、右子和父亲指针。
在成立哈夫曼树之前还需要对出现的字符和权重进行统计和记录,而且概念一个能够挑选出最小权重的函数。
初始化树节点以后开始成立哈夫曼树。
先在所有可能出现的字符中挑选出当前权重最小的两个字符,将这两个字符别离作为新节点的左子和右子成立一个小的二叉树,并将两个字符的权重之和赋值给新节点,将新二叉树放入挑选字符中,再将挑选过的两个字符从挑选列表中淘汰掉。
依次对列表中剩下的字符进行权重最小的挑选,直到根节点(若是编码表共有N个字符,则2*N-1就为最终根节点)为止,也就是当挑选列表为空的时候,哈夫曼树即成立完成。
对于哈夫曼编码树来讲,由于哈夫曼编码是前缀码,所以所有要编码的字符最终都将是这颗树的叶子节点,而其它节点并无真正的字符意义。
即当哈夫曼编码树成立以后,对树的所有叶子节点进行打印可明白是不是有字符遗漏或多余。
成立哈夫曼编码表。
成立编码表时要按照每一个出现的字符的权重对成立的哈夫曼树的每一个叶子节点进行编码。
编码时要从叶子节点动身向根节点进行逆向编码。
判断若是当前节点为左子则对其编码‘0’,若是当前节点为右子则对其编码‘1’。
以此类推动行编码直到根节点为止。
现在的编码是逆向的,所以需要将码值逆向存储。
依次对每一个叶子节点进行编码操作,即可取得当前哈夫曼树的编码表。
对于码值的逆向存储能够利用栈结构,先将一个码的每一步编码存入栈,再在一个码结束后出栈至空。
固然也能够概念一个字符型数组,将值从后向前存入数组,再将数组有值部份粘贴到新的数组中进行存储。
本次采用了后者,因为个人以为为此一步操作成立栈结构不划算,而且前一个设计也已经熟练掌握了栈的方式,此处进行新的尝试会更好。
对文件进行编码。
第一需要成立一个原始文件,在文件中输入需要编码的内容。
以后将文件打开,将其中的内容存储到字符串中以便程序编码挪用。
开始对需要编码的字符进行编码,将字符一一读取与方才成立的编码表中的每一个叶子节点代表的字符进行比较,找出相同的对象,并将当前节点的编码打印到屏幕,并将编码存入到新建的密码文件当中。
对文件进行解码。
先打开密码文件,将之前编码后取得的密文内容存储到字符串中以便解码挪用。
开始对密文的字符串进行解码,树索引从根节点开始走,当密文中的当前字符是‘0’的时候,则索引走向左子节点;
当是‘1’的时候,则走向右子节点。
以此类推,一直走到叶子节点为止,则当前叶子节点所代表的字符即为前一段密文的解码结果,。
再对下一个字符依次从根节点开始解码,如此循环对每一段密文进行解码直到解码结束。
将解码打印到屏幕,并将解码结果存入到新的解码文件当中。
在解码之前,还应该先确认之前是不是成立了哈夫曼树而且是不是构建了编码表。
不过由于本次将‘a’到‘z’都进行了编码,所以此步省略了,因为编码表是唯一的。
需要的时候能够在Encoder函数中先进行判定。
将编码和解码写在了一路,能够在运行时进行选择挪用。
二、算法流程图
第一步:
成立哈夫曼树。
图1成立哈夫曼树的算法流程图
第二步:
构建哈夫曼编码表。
图2构建哈夫曼编码表的算法流程图
第三步:
编码。
图3编码算法流程图
第四步:
解码。
图4解码算法流程图
四、运行结果
原文文件:
图5中缀转后缀运行结果图
编码图:
图6编码图
密文文件:
图7密文文件图
解码图:
图8解码图
译文文件:
图9译文文件图
整体运行图:
图10编码解码整体运行图
五、碰到的问题及解决
这部份我主要碰到了如下两个问题,其内容与解决方式如下所列:
●第一个问题是权重的挑选部份出现了错误
解决办法:
一开始对于挑选最小权重的代码编写如下:
voidSelectMin(HFMTT,inti,int*p1,int*p2)
{
intj,min=999;
for(j=0;
j<
i;
j++)
{
if(T[j].parent==-1&
&
min>
T[j].weight)
min=T[j].weight;
*p1=j;
}
min=999;
T[j].weight&
j!
=(*p1))
*p2=j;
}
因为权重中最大的就是字符e的权重103,所以为初始值min赋值时感觉999就已是无穷大了。
可是后来发觉编码不知确,就开始试探是什么问题。
发觉每次挑选都将会把最小的两个权重进行相加,所以专门快就会超过999,编码自然就出现了问题。
所以后来将min概念成了long型,并赋值999999,问题就解决了。
●第二个问题是生成编码表的时候如何将逆向编码正向存储
对于求编码的时候,由于是从叶子节点向根按序而求,所以编码结果将是逆向的。
一开始想到的办法是利用栈的结构,将编码依次存入栈中,再在一个字符编码结束时将栈倒空,如此就可以够将编码正向存储了。
可是又在考虑若是不用栈时候也能够做到。
后来想到了strcpy函数对字符数组进行链接。
所以就可以够概念一个数组,从后向前存储编码,再在一个字符编码结束时将那个数组有值的从头存入新数组中,即能够成为正向编码了。
最终实现编码如下:
HFCodehfEn(HFMTT)
{
inti,f,c,start;
HFCodehc;
char*cd;
hc=(char*)malloc((N+1)*sizeof(char*));
cd=(char)malloc(N*sizeof(char));
cd[N-1]='
\0'
;
for(i=0;
i<
N;
i++)
start=N-1;
for(c=i,f=T[i].parent;
f!
=-1;
c=f,f=T[f].parent)
if(T[f].left==c)
cd[--start]='
0'
else
1'
hc[i]=(char*)malloc((N-start)*sizeof(char));
strcpy(hc[i],&
cd[start]);
returnhc;
六、心得体会
通过对本次的编写,使我掌握了哈夫曼编码的特点、存储方式和大体原理,培育了我运用C语言正确编写程序和调试程序的能力。
哈夫曼编码的结构取决于可能出现的字符的个数和其所对应的权值,权值大的编码短,权值小的编码长。
如此的结构会利用比较小的空间存储数据。
而且,利用树的结构对其编码和对其解码,也是比较规格话,比较方便的。
本次编程还运用了结构体,便捷的对树节点和树和编码表进行概念和挪用。
而且了解到当求解一个算法时,不是拿到问题就不假思索去做,而应该第一对它有个整体的概念,再一步步对其进行分析。
在分析的进程中也应该学会随时总结问题,将碰到的问题融会贯通,以便在未来需要的时候能够应用自如。
本次设计中也存在一些一开始不容易解决的问题,但当对算法的进一步分析和对相关信息的查阅,也比较顺利的完成了设计。
虽然路途比较艰辛,但奋斗的经历却成了最宝贵的人生经验。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 语言 哈夫曼 编码 译码
![提示](https://static.bdocx.com/images/bang_tan.gif)