哈夫曼编码(Huffman Coding)-贪心策略

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

       面试题常常会考的一种思想,笔试题就更不用说了,选择题直接让你构造哈夫曼树。

  哈夫曼编码的图形构造是一棵树,每个节点具有权值,权值越大的节点越靠近树根,越小的节点就越远离树根,从它的定义来看,想到的就是贪心策略。

  首先如何构造哈夫曼编码树:每次从树集合中找出权值最小的两棵树分别作为左、右子树,然后合并它们作为他们的父节点,其权值为两颗子树的权值和。

步骤 :

  1 :确定合适的数据结构(要知道他的左右子树,双亲,权值)

  2:初始化,构造n颗节点为n的字符单节点树集合T={t1,t2,t3,t4···········tn},保证按权值排序,并且每棵树只有树根

  3:如果集合中只剩下一棵树,那么哈夫曼树就构造成功,直接跳转到步骤6,否则就是从集合中继续拿出权值最小的子树x作为左子树,第二小的y作为右子树,并将它们合并到一颗z树中,

    z的权值为左右子树权值之和

  4:从T集合中删除x,y 把新树z加入到集合T中

  5:重复步骤3~4

  6:约定左分支上的编码都是0,右分支上的编码都是1,从叶子节点开始逆序求出树的编码

 


  对于编码字符出现的频率:

1)将信源符号的概率按减小的顺序排队。

2)把两个最小的概率相加,并继续这一步骤,始终将较高的概率分支放在右边,直到最后变成概率1。

3)画出由概率1处到每个信源符号的路径,顺序记下沿路径的0和1,所得就是该符号的霍夫曼码字。   

4)将每对组合的左边一个指定为0,右边一个指定为1(或相反)。

例如:假定下表字符出现频率:  

找出两个最小频率的节点分别作为子树,频率相加作为父节点

 

依次进行,直到只有一棵树时:

 

 从叶子节点开始往上回溯编码,将每个节点的左孩子节点指定为0,右孩子节点指定为1:

从树根往下遍历,得到相应的编码:

B:11

A:10

D:011

C:010

E:00

  Huffman编码使得每一个字符的编码都与另一个字符编码的前一部分不同,不会出现像’A’:00,  ’B’:001,这样的情况,解码也不会出现冲突。

原文地址:https://www.cnblogs.com/ye-buaascse/p/11850809.html