7.9 哈夫曼树(Huffman Tree)

二叉树的知识还没完哈,我们来介绍一下哈夫曼树。

参考博客:

哈夫曼树

haffman哈夫曼树——贪心算法(java)

哈夫曼树原理,及构造方法

概述

给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。

首先我们先学会这样一个概念:树的带权路径长度,用WPL表示

WPL = \sum_{i=1}^{n} w_{i}l_{i}

其中,n表示叶子结点的数目,wi和li 分别表示叶子结点的权值和根到该结点之间路径的长度。 

我们着重解释一下路径长度,结点的路径长度,其实就是看从根结点到该结点的分支数,也就是需要查找的次数,如果是根结点的左孩子,查找次数就是1,只需要与根结点的信息比较一次即可查到。有些文章管路径长度叫 构造价值

理解了这一概念,我们来看一棵树的WPL,如下grade 1-5 代表学生成绩从低到高的五个阶段。

同样这几个结点,不同的树结构WPL也是不同的。看上图,概率极低的grade=1的情况,为何只查找一次就查到了呢?岂不是很浪费?因此我们想到,让频率高的值查找更快。

这就是哈夫曼树的基本原理。让查找效率更高,让出现频率更高的元素(权重大的),拥有较少的查找次数。

哈夫曼树的构造

根据以上原理我们再学习哈夫曼树的构造就容易多了。可以参考上面介绍的博客。贪心算法来构造即可,从权重小的结点开始合并,不再赘述。

哈夫曼编码

哈夫曼编码的知识一般从两个方面认识:

  • 给定一段字符串,如何 对字符进行编码 ,可以使得该字符串的编码存储空间最少?
  • 怎么进行不等长编码?如何避免二义性? (前缀码prefix code :任何字符的编码都不是另一字符编码的前缀)

我们来看百度百科的介绍,这就是哈夫曼编码的实际应用及其应用价值。

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

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

 在数据通信中,需要将传送的文字转换成二进制的字符串,用0,1码的不同排列来表示字符。例如,需传送的报文为“AFTER DATA EAR ARE ART AREA”,这里用到的字符集为“A,E,R,T,F,D”,各字母出现的次数为{8,4,5,3,1,1}。现要求为这些字母设计编码。要区别6个字母,最简单的二进制编码方式是等长编码,固定采用3位二进制,可分别用000、001、010、011、100、101对“A,E,R,T,F,D”进行编码发送,当对方接收报文时再按照三位一分进行译码。显然编码的长度取决报文中不同字符的个数。若报文中可能出现26个不同字符,则固定编码长度为5。然而,传送报文时总是希望总长度尽可能短。在实际应用中,各个字符的出现频度或使用次数是不相同的,如A、B、C的使用频率远远高于X、Y、Z,自然会想到设计编码时,让使用频率高的用短码,使用频率低的用长码,以优化整个报文编码。

为使不等长编码为前缀编码(即要求一个字符的编码不能是另一个字符编码的前缀),可用字符集中的每个字符作为叶子结点生成一棵编码二叉树,为了获得传送报文的最短长度,可将每个字符的出现频率作为字符结点的权值赋予该结点上,显然字使用频率越小权值越小,权值越小叶子就越靠下,于是频率小编码长,频率高编码短,这样就保证了此树的最小带权路径长度效果上就是传送报文的最短长度。因此,求传送报文的最短长度问题转化为求由字符集中的所有字符作为叶子结点,由字符出现频率作为其权值所产生的哈夫曼树的问题。利用哈夫曼树来设计二进制的前缀编码,既满足前缀编码的条件,又保证报文编码总长最短。

哈夫曼静态编码:它对需要编码的数据进行两遍扫描:第一遍统计原数据中各字符出现的频率,利用得到的频率值创建哈夫曼树,并必须把树的信息保存起来,即把字符0-255(2^8=256)的频率值以2-4BYTES的长度顺序存储起来,(用4Bytes的长度存储频率值,频率值的表示范围为0--2^32-1,这已足够表示大文件中字符出现的频率了)以便解压时创建同样的哈夫曼树进行解压;第二遍则根据第一遍扫描得到的哈夫曼树进行编码,并把编码后得到的码字存储起来。

哈夫曼动态编码:动态哈夫曼编码使用一棵动态变化的哈夫曼树,对第t+1个字符的编码是根据原始数据中前t个字符得到的哈夫曼树来进行的,编码和解码使用相同的初始哈夫曼树,每处理完一个字符,编码和解码使用相同的方法修改哈夫曼树,所以没有必要为解码而保存哈夫曼树的信息。编码和解码一个字符所需的时间与该字符的编码长度成正比,所以动态哈夫曼编码可实时进行。


ok,哈夫曼树和哈夫曼编码的知识也就这些,理解其应用价值,会简单的构造一颗哈夫曼树即可。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值