霍夫曼压缩算法

时间:2009-05-24 08:55:38

标签: algorithm compression huffman-code

我使用huffman算法实现了文件压缩,但我遇到的问题是,要启用压缩文件的解压缩,使用的编码树或代码本身也应该写入文件。问题是:我该怎么做?在压缩文件的开始处编写编码树的最佳方法是什么?

9 个答案:

答案 0 :(得分:5)

Basic Compression Library (BCL)中有一个非常标准的霍夫曼编码实现,包括将树写入文件的递归函数。看看huffman.C。它只是按顺序写出叶子,因此解码器可以重建相同的树。

BCL也很不错,因为其中还有一些非常直接的压缩算法。如果你需要推出自己的算法,这非常方便。

答案 1 :(得分:3)

首先,您是否考虑使用标准压缩流(如.net中的GZipStream)?

关于如何/在何处编写数据,您可以使用Seek操作Streams位置(甚至可以预留空间)。如果您提前知道树的大小,则可以在该位置之后开始书写。但是您可能希望将编码树放在实际数据之后,并确保知道它从何处开始。即,在前面保留一点空间,写入压缩数据,记录位置,写树,到前面并写出位置。

答案 2 :(得分:2)

假设您压缩8位符号(即字节)并且算法是非自适应的,最简单的方法是不存储树而是存储值的分布。例如,通过存储找到字节0的频率,字节1的频率,...,字节255的频率。然后,当读回文件时,您可以重新组装树。这是最简单的解决方案,但需要最大的存储空间(例如,要覆盖大文件,每个值需要4个字节,即1kb)。

你可以通过不准确存储文件中每个字节的频率来优化这一点,而是将值标准化为0..255(0 =找到最少,......),在这种情况下你会只需要保存256个字节。基于这些值重新组装树将导致相同的树。(这不符合Edmund和问题759707所指出的那样 - 请参阅更多链接和答案你的问题)

P.S。:正如Henk所说,使用seek()可以让你在文件的开头留出空格来存储值。

答案 3 :(得分:2)

大多数实现都使用规范的霍夫曼编码。您只需以紧凑的方式存储符号长度。实施时:shcodec。 另一种方法是使用半静态霍夫曼编码(周期性重新缩放),然后你不必存储任何树。

答案 4 :(得分:1)

不是将代码树写入文件,而是写下每个字符的查找频率,因此解压缩程序可以生成相同的树。

答案 5 :(得分:1)

最天真的解决方案是按预先解析压缩树,并在文件的标题中写入256个值。

答案 6 :(得分:1)

由于霍夫曼树中的每个节点都是具有两个子节点的分支或叶子,因此您可以使用单个位来明确地表示每个节点。对于叶子,请立即使用该节点的8位。

e.g。对于这棵树:

    /\
   /\ A
  B /\
   C  D

您可以存储001 [B] 01 [C] 1 [D] 1 [A]

(事实证明这正是前面发布的huffman.c示例中发生的事情,但不是上面描述的内容)。

答案 7 :(得分:0)

最好发送字符的频率并在接收端构建树。对于固定字母表,此数据的大小将保持不变。我想这必须是可序列化的并放在文件中。发送树取决于它的实现,对于我所尝试的,基于数组的方法导致更多的内存未用于树,因为树在大多数时间可能不是平衡树。如果树是平衡的,那么数组表示将产生最佳选项。

Harisankar Krishna swamy

答案 8 :(得分:0)

您是否尝试过自适应霍夫曼编码?从第一眼看,似乎根本不需要发送树,但需要更多的工作来优化和同步树木。