数据结构——哈夫曼树与哈夫曼编码

时间:2021-11-07 10:33:28

1.哈夫曼编码 Huffman code:

  是一种文本压缩算法,这种算法依据的是不同符号在一段文本中相对出现的频率。假设一个文本是由a,u,x,z组成的字符串,其长度为1000,每个字符用1字节来存储,共需要1000字节,即8000位。如果每个字符用2位二进制来编码:00=a, 01=x, 10=u, 11=z.那么,用2000位空间即课表示1000个字符。此外,我们还需要一定的空间来存放编码表,它可以采用如下的存储格式:

    符号个数,代码1,符号1,代码2,符号2,...

  符号个数即以及每个符号分别占8位,每个代码占 log2(符号个数) 向上取整 位。因此,在这个例子中,编码表需要5*8+4*2 = 48 位。压缩比为8000/2048 = 3.9。

  即一段文本的压缩结果是:压缩有的字符串+编码表。

  在字符串aaxuaxz中,a出现3。一个符号出现的次数称为频率frequency. 当不同字符出现的频率有很大差别时,我们可以通过可变长编码来缩短编码串的长度。这带来一个 问题:每次提取多少为代码来解释符号?——只要没有任何一个代码是另一个代码的前缀就可以!因此,当从左到右检查编码位串时,可以得到与一个确切的代码相匹配的字符。

  可以利用扩展二叉树(增加了外部节点的二叉树)来派生一个特殊的类,对具有上述前缀性质的代码,实现可变长编码。这个用于编码的类称为霍夫曼编码。

  在一棵扩展二叉树中,从根到外部节点的路径可用来编码,方法是用0表示向左子树移动一步,1表示向右子树移动一步。我们用S表示待编码字符组成的字符串,F(x)是字符x的出现频率。

  对于一棵具有n个外部节点的扩展二叉树,且外部节点标记为1,2,...,n其对应的编码位串的长度为: WEP = ΣL(i)*F(i)

  L(i)是从根到外部节点i的路径长度(即路径的边数);WEP是二叉树的加权外部路径长度 weighted external path length. 为了缩短编码串的长度,必须使用二叉树代码,二叉树的外部节点与要编码的字符串的字符对应,且WEP最小。一棵二叉树,如果对一组给定的频率,其WEP最小,那么这颗二叉树称为霍夫曼树 Huffman tree。

  用霍夫曼编码对一个一个字符串或一段文本进行编码,需要做的是:

  1.确定字符串的符号和它们出现的频率。

  2.建立霍夫曼树,其中外部节点用字符串中的符号表示,外部节点的权用相应符号的频率表示。

  3.沿着从根到外部节点的路径遍历,取得每个符号的代码。

  4.用代码替代字符串中的符号\