Huffman Tree

什么是Huffman coding?

霍夫曼编码(Huffman Coding)是一种编码方式,是一种用于无损数据压缩算法。1952年,David A. Huffman在麻省理工攻读博士时所发明的,并发表于《一种构建极小多馀编码的方法》(A Method for the Construction of Minimum-Redundancy Codes)一文。

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

 

例如,在英文中,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是最小的。

 

算法原理:

    ht首先被提出来,是为了解决这样的问题:

    对于N种数据(比如5种数据:A、B、C、D、E),在出现的频率已
知的情况下(比如分别出现了3、5、2、6、4次),如何用不等长的01
串来分别表示它们,使01串的总长度最短。

    比如原始串:ABADBCBDABEDBDEDCEDE

    对于这个问题,首先得到:任何一个01串都不能是其他01串的前缀
。也就是说,如果用“10”来表示A,那么其他01串就不能以“10”开
头。
    建立01串的步骤如下:

    首先找到出现最少的两个数据(A、C),分别以它们为左右子树,
建立一个二叉树。并将它们出现次数之和作为根节点:

1)

    5   5B  6D  4E
   / /
  3A 2C

    然后从剩下的4个数举重找到两个最小的,做同上的操作,知道只
剩一个数据为止:

2)

    5     9    6D
   / /   / /
  3A 2C 5B 4E
  
3)

      11      9
     /  /    / /
    5   6D  5B 4E
   / /
  3A 2C
  
4)
           20
          /  /
       11      9
      /  /    / /
     5   6D  5B 4E
    / /
   3A 2C

    最后从根节点开始,每个左子树填0,右子树填1:

             ROOT
            /    /
           0      1
          / /    / /
         0  1D  0B 1E
        / /
       0A 1C

    这样每个数据对应的01串就是从根节点到数据所在的叶子节点的路
径:

A: 000
B: 10
C: 001
D: 01
E: 11

    这样原始串ABADBCBDABEDBDEDCEDE就成了:

000100000110001100100010110110011101001110111

 

通过建Huffman Tree的方法对文本编码、译码

 

有了上面的算法,使用Huffman编码的时候就方便了。比如我们要发送ABC,只要发送00010001就可以了,每个编码直接都不需要用分割符号。因为解析的时候,诸位提取,对照Huffman编码进行解析就可以了。比如先读到0,编码表里没有0,就继续。然后又读到0,还没有找到00,继续读,等再次读到0这个时候就有了一个匹配A,然后继续,就又得到了B和C。

 

下面是编码的具体实现:
类BaseNode定义了基本的节点:

 

部分内容转自 http://blog.csdn.net/schumyxp/archive/2008/04/23/2317183.aspx

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值