1

在我在课堂上使用的书中(以及我从其他几个地方看到的),创建霍夫曼树的算法似乎源于

(1) 根据正在读入的任何文件或字符串中每个字符的频率构建一个 minheap。

(2) 从 minheap 中弹出 2 个最小值并将它们的权重组合到一个新节点中。

(3) 将新节点重新插入到同一个 minheap 中。

我对第 3 步感到困惑。我见过的大多数霍夫曼树的属性更类似于最大堆而不是最小堆(尽管它们不是完整的树)。也就是说,根包含最大权重(或者更确切地说是权重组合),而它所有的孩子的权重都较小。当组合节点放回 minheap 时,此实现如何给出霍夫曼树?我已经为此苦苦挣扎了一段时间。

这里已经发布了一个类似的问题(和我同一本书):我不明白这个霍夫曼算法实现

如果您想查看 (3) 中描述的确切功能。

谢谢你的帮助!

4

1 回答 1

1

霍夫曼树通常不是完全二叉树,因此也不是最小堆。

霍夫曼算法很容易理解为构建树的频率列表。首先构建小分支,最终将全部合并为一棵树。每个列表项以一个符号开始,后来可能是一个符号或已构建的子树。每个列表项总是有一个频率(通常是整数)。

从列表中取出两个最小的频率(关系无关紧要 - 任何选择都会产生最佳代码,尽管可能有不止一个最佳代码)。从这两个构造一个单级二叉树,其中两个叶子是这些频率的符号。添加频率以生成表示树的新频率。将该频率放回列表中。现在列表中的频率减少了一个。

重复。现在,在每一步构建的二叉树可能在每个分支上都有符号叶子,或者一个叶子和一个先前构建的树,或者两棵树(最早在第三步中)。

继续前进,直到列表中只剩下一个频率。这将是所有原始频率的总和。该频率具有与之关联的完整霍夫曼树。

现在您可以(任意)为每个二进制分支分配 0 和 1。您可以通过从根遍历树到符号来构建代码或解码代码。该遍历的分支中的位按该符号的霍夫曼码的顺序排列。

于 2012-07-29T04:36:06.780 回答