haffman树

来源:互联网 发布:solarman软件下载 编辑:程序博客网 时间:2024/05/01 10:35
haffman树

1. 简介

     haffman编码主要用于数据压缩,huffman树可以解决二进制编码时码长最短且无二义性。haffman树是haffman编码的基础。根据字符出现的频率,利用haffman树可以构造一种不等长的二进制编码,并且构造所得的haffman编码是一种最优前缀编码,可以使编码后的电文长度最短,且保证任何一个字符的编码都不是同一字符集中另一字符码的前缀。

 

2.haffman树的概念

     haffman树是带权路径长度最小的二叉树。

     几个基本的概念:

     结点的路径长度:从根结点到该结点的路径上的边数。

     树的路径的长度:树中每个叶子结点的路径长度之和。

     结点的带权路径长度:结点的路径长度与结点权值的乘积。

     树的带权路径长度:树的带权路径长度WPL(Weight Path Length)是树中所有叶子结点的带权路径长度之和。

 

3.haffman树构造方法

  算法:

  (1)根据权值w1,w2,w3,...,wn构造n个二叉树F={T1,T2,...,Tn},其中Ti是只含权值wi的结点

  (2)从F中选两个权值最小的二叉树Ti和Tj,构造一个根结点R,R的权WR为Wi+Wj。

  (3)从F中删除Ti和Tj,加入新的树根结点R到F中。

  (4)重复步骤2和步骤3,直到F中只有一棵树为止。

 

haffman树构建示意图:

 

 

4.haffman编码及其实现

  haffman树是haffman编码的基础,利用haffman树可以构造haffman编码。haffman编码的基本原理是频繁使用的数据用较短的代码代替,而较少使用的数据则用较长的代码代替,这样可以使报文中的编码数减到最小,从而达到压缩的目的。

    例如给出一段报文: ABCD ABCD CBD BD B DBCB

    报文中出现的字符集{A,B,C,D},其中B出现的次数最多,7次,其次是D,5次,然后依次是C和A,分别出现的次数为4和2。对4个字符进行编码,至少需要两位二进制码。首先给出不经过压缩的方法,每个字符两位二进制编码为A:00   B:01   C:10   D:11,则将原文编码所得结果如下:

    00011011  00011011 100111 0111 01 11011001   编码长度为36

采用 haffman编码,则 B:0  D:10  C:110  A:111

     报文编码结果: 111011010 111011010 110010 010 0 1001100  编码长度为35

 

    利用构建的haffman树的方法可以得到报文的haffman编码,具体算法如下:

 (1)统计处每个符号出现的频率,例如上例中的频率统计为{2/18,7/18,4/18,5/18}.

 (2)从左到右把上述的频率按从小到大的顺序排列。

 (3)每一次挑出的最小的两个值作为二叉树的两个叶结点,并将它们合并后的结点作为根结点,这两个结点不再参与比较,新的根结点参与比较。

 (4)重复上一步,直到最后得到和为1 的根节点。

 (5)将新形成的二叉树的左结点标0,右结点标1。把从最上面的根结点到最下面的叶子结点途中遇到的0,1序列串起来,就得到各个符号的编码

 当报文中高频字符频率较高时,haffman呈现出较高的压缩比。haffman不仅应用于文本编码,而且同样应用于图像编码等领域中。haffman优点在于:

       a)  对于给出的报文可以得到最短编码

       b)  非同一个字符的任意两个字符A和B,不会出现A的编码时B的编码的前缀这种情况。这是因为如果设编码字符集为{C1,C2,...,Cn},那么根到任何叶子结点Ci的路径都不会是另一个编码的前缀。因而两个字符之间不需要分隔符。

 

    由上文可知,产生haffman编码需要对原始数据扫描两遍。第一遍扫描是为了统计出原始数据中的每个值出现的频率,第二遍是建立haffman树进行编码,由于需要建立二叉树并遍历二叉树生成的编码,因此数据压缩和还原速度比较慢。 

原创粉丝点击