哈夫曼编码是一种编码方式,是可变字长编码(VLC)的一种。以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据
压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。这一术语是指使用一张特殊的
编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出
现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数
据的目的)。这种方法是由David.A.Huffman发展起来的。 例如,在英文中,e的出现概率很高,而z的出现概率则最低。当利用哈夫曼编码
对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。用普通的表示方法时,每个英文字母均占用一
个字节(byte),即8个位。二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对于英文中各个字母出现概率的较
准确的估算,就可以大幅度提高无损压缩的比例。
其中哈夫曼编码的构造过程为:
(1)初始化,根据符号概率的大小按由大到小顺序对符号进行排序。 (2)把概率最小的两个符号组成一个新符号(节点),即新符号的概率等于这两个符号概率之和。 (3)重复第2步,直到形成一个符号为止(树),其概率最后等于1。 (4)从编码树的根开始回溯到原始的符号,并将每一左分枝赋值为0,右分枝赋值为0。前三步为构造哈夫曼树过程,既而在第四步遍历构造出的哈夫曼树,得到各字符的最优前缀码.为了快速实现取集合中的最小值及向集合中插入新的元素,可以使用二叉堆来实现,二叉堆的定义及实现请另行参考.(注:由于ASCII码及
char型数据范围的限制,编码过程中生成的哈夫曼树不会非常大,所以生成哈夫曼树所需要的时间在整个压缩过程中显得微不足道,可用其它方式来生成哈夫曼树.)以一棵生成的哈夫曼树为例(图片来自:http://blog.163.com/yuang_yu_ping/blog/static/4693287620098172049346/):图片中的哈夫曼树对应的绿色即叶结点为待编码字符,对应的前缀码分别为:A : 10C : 01D : 11E : 000M : 001在文本文件的压缩过程中,首先取ASCII字符对应的出现次数,然后对 0x00~0xff 这些字符根据出现频率生成对应的前缀码,然后读取
文件 ,为每一个字符进行编码.编码问题已经解决了,可是如果要实现文件压缩,压缩文件的编码如何进行存储呢? 首先明确一点,源文件压缩之后的编码对应的是二进制的
位段,而C语言中每个char 类型占用八位的空间,我们可以把编码后的二进制位以八位为一段,生成对应的字符来存储.对最后不足八位的二进制段,补足八位,用一个字符表示,依次存储这些转化来的字符,即可生成压缩文件.另,为了解压的需要,我们要存储编码的信息至压缩文件中,可以采用源文件中各字符出现的频率来记录,解码时读取这些信息,再利用这些信息
重新生成一棵同样的哈夫曼树,另外压缩文件头中存储有最后一个字符实际占用的位数,用以在解压时对最后一个字符正确处理.