使用最小堆的霍夫曼树实现

时间:2012-07-29 02:59:39

标签: c++ tree heap huffman-code

在我正在为我的班级使用的书中(以及我从其他一些地方看到的),看起来创建一个霍夫曼树的算法源于

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

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

(3)将新节点重新插入相同的minheap。

我对第3步感到困惑。我见过的大多数霍夫曼树的属性更像是最大堆而非minheap(虽然它们不是完整的树)。也就是说,根包含最大权重(或权重的组合),而所有孩子的权重都较小。当组合节点重新进入minheap时,此实现如何提供一个huffman树?我一直在努力解决这个问题。

此处已发布类似问题(与我同书):I don't understand this Huffman algorithm implementation

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

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

霍夫曼树通常一个完整的二叉树,因此不是一个小堆。

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

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

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

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

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