算法分析11

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于哈夫曼编码理论对于文件的压缩

姓名:朱元军学号:201226630328 班级:软件1203

简介:霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩的

熵编码(权编码)算法。1952年,David A. Huffman在麻省理工攻读博士时所发明的,并发表于《一种构建极小多余编码的方法》(A Method for the Construction of Minimum-Redundancy Codes)一文。

1.哈夫曼算法的定义

简单地说就是,一组符号(Symbol)和其对应的权重值(weight),其权重通常表示成机率(%)。例:符号集合S={s1,s2,···,Sn},其S集合的大小为n。权重集合W={w1,w2,···,Wn},其W集合不为负数且Wi=weight(Si),1 ≤i ≤n。演算过程:进行霍夫曼编码前,我们先创建一个霍夫曼树。

⒈将每个英文字母,依照出现频率由小排到大,最小在左。

⒉每个字母都代表一个终端节点(叶节点),比较F.O.R.G.E.T五个字母中每个字母的出现频率,将最小的两个字母频率相加合成一个新的节点。如Fig.2所示,发现F与O的频率最小,故相加2+3=5。

⒊比较5.R.G.E.T,发现R与G的频率最小,故相加4+4=8。

⒋比较5.8.E.T,发现5与E的频率最小,故相加5+5=10。

⒌比较8.10.T,发现8与T的频率最小,故相加8+7=15。

⒍最后剩10.15,没有可以比较的对象,相加10+15=25。

(二)进行编码

1.给霍夫曼树的所有左链结'0'与右链结'1'。

2.从树根至树叶依序记录所有字母的编码,如Fig.3。

2:基本介绍

在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。

例如,在英文中,e的出现机率最高,而z的出现概率则最低。当利用霍夫曼编码对一篇英文进行压缩时,e极有可能用一个比特来表示,而z则可能花去25个比特(不是26)。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个比特。二者相比,e 使用了一般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。

霍夫曼树又称最优二叉树,是一种带权路径长度最短的二叉树。所谓树的带权路径长度,就是树中所有的叶结点的权值乘上其到根结点的路径长度(若根结点为0层,叶结点到根结点的路径长度为叶结点的层数)。树的路径长度是从树根到每一结点的路径长度之和,记为WPL=(W1*L1+W2*L2+W3*L3+...+Wn*Ln),N个权值Wi(i=1,2,...n)构成一棵有N个叶结点的二叉树,相应的叶结点的路径长度为Li(i=1,2,...n)。可以证明霍夫曼树的WPL是最小的。

3:发展历程

1951年,霍夫曼和他在MIT信息论的同学需要选择是完成学期报告还是期末考试。导师Robert M. Fano给他们的学期报告的题目是,查找最有效的二进制编码。由于无法证明哪个已有编码是最有效的,霍夫曼放弃对已有编码的研究,转向新的探索,最终发现了基于有序频率二叉树编码的想法,并很快证明了这个方法是最有效的。

由于这个算法,学生终于青出于蓝,超过了他那曾经和信息论创立者克劳德·香农共同研究过类似编码的导师。霍夫曼使用自底向上的方法构建二叉树,避免了次优算法香农-范诺编码的最大弊端──自顶向下构建树。

4 实现方法

实现霍夫曼编码的方式主要是创建一个二叉树和其节点。这些树的节点可以存储在数组里,数组的大小为符号(symbols)数的大小n,而节点分为是终端节点(叶节点)与非终端节点(内部节点)。

一开始,所有的节点都是终端节点,节点内有三个字段:

1.符号(Symbol)

2.权重(Weight、Probabilities、Frequency)

3.指向父节点的链结(Link to its parent node)

而非终端节点内有四个字段:

1.权重(Weight、Probabilities、Frequency)

2.指向两个子节点的链结(Links to two child node)

3.指向父节点的链结(Link to its parent node)

基本上,我们用'0'与'1'分别代表指向左子节点与右子节点,最后为完成的二叉树共有n个终端节点与n-1个非终端节点,去除了不必要的符号并产生最佳的编码长度。

过程中,每个终端节点都包含着一个权重(Weight、Probabilities、Frequency),两两终端节点结合会产生一个新节点,新节点的权重是由两个权重最小的终端节点权重之总和,并持续进行此过程直到只剩下一个节点为止。

实现霍夫曼树的方式有很多种,可以使用优先队列(Priority Queue)简单达成这个过程,给与权重较低的符号较高的优先级(Priority),算法如下:

⒈把n个终端节点加入优先队列,则n个节点都有一个优先权Pi,1 ≤ i ≤ n

⒉如果队列内的节点数>1,则:

⑴从队列中移除两个最大的Pi节点,即连续做两次remove(max(Pi), Priority_Queue)

⑵产生一个新节点,此节点为(1)之移除节点之父节点,而此节点的权重值为(1)两节点之权重和

⑶把(2)产生之节点加入优先队列中

⒊最后在优先队列里的点为树的根节点(root)

而此算法的时间复杂度(Time Complexity)为O(n log n);因为有n个终端节点,所以树总共有2n-1个节点,使用优先队列每个循环须O(log n)。

相关文档
最新文档