霍夫曼压缩是如何工作的

时间:2013-07-05 07:23:42

标签: huffman-code

当我尝试使用Huffman代码对以下流进行编码时遇到了一些问题。 如果编码系统是

A:0 B:10 C:110 D:111

然后序列ABBADC将是010100111110。 我收到它时如何解码这个比特流? 编码系统是否必要? 如果是这样,我该如何发送此表? 如果没有,我应该如何解码它们?

3 个答案:

答案 0 :(得分:1)

你必须建一棵树

   Start
 /0    \1
 |    /0 \1 
 A   |   / \
     B   | |
         C D

按照二进制数字的每一步移动它。每次找到叶子 - 返回根

您应该将此表格发送到文件的特殊标题部分或完全单独发送

答案 1 :(得分:1)

您不需要发送表,只需要发送位长度。即,1,2,3,3。给定比特长度,可以在编码和解码两端以相同的方式构造规范前缀码。有关规范代码的详情,请参阅this answer

解码前缀代码的方法有很多种。你可以一点一点地走,好像你正在穿越一棵树,最终到达一个象征的叶子。然后从树的根开始返回下一位。

对于规范代码,其中确保较短的长度具有比较长的长度更低的整数值,将比特收集为整数并与每个长度的值表进行比较。一旦建立了长度,整数就会对符号表进行索引。这就是示例代码puff.c所做的。

最快的方法之一是拥有一个表,其长度包含最长的代码,其中每个表条目是符号和位数。具有较少位的代码具有多个表条目。在这种情况下:

000: A 1
001: A 1
010: A 1
011: A 1
100: B 2
101: B 2
110: C 3
111: D 3

然后你读取三位,查找它,在表中发出符号,并消耗指示的位数。然后根据需要获得更多位以返回三位并重复。如果到达输入的末尾,只需填充零位,但要注意多少。如果解码的代码使用填充位,则标记错误。

这是zlib's inflate代码所做的事情,虽然它builds a two-level table稍微复杂一点,因此不会花太多时间来构建长表。

答案 2 :(得分:0)

传统上,树数据结构用于存储霍夫曼数据。因此,当您处理A,B,C,D时,您将继续构建二叉树。编码的值,即A,B,C,D存储在叶子上。 当您收到位流时,您只需遍历已经拥有的树来解码代码。

在你的情况下,如果你只有这4个输入,那么我建议使用一个比树更多的散列图,因为它会让你的查找更容易。