【问题标题】:I don't understand this Huffman algorithm implementation我不明白这个霍夫曼算法的实现
【发布时间】:2010-07-16 23:41:28
【问题描述】:
    template<class T>
    void huffman(MinHeap<TreeNode<T>*> heap, int n)
    {
      for(int i=0;i<n-1;i++)
      {
        TreeNode<T> *first = heap.pop();
        TreeNode<T> *second = heap.pop();
        TreeNode<T> *bt = new BinaryTreeNode<T>(first, second, first.data, second.data);
        heap.push(bt);
      }
    }

在我的Fundamentals of Data Structures in C++ 教科书中,它给出了霍夫曼编码的 2 页定义,以及上面的代码。对我来说,这本书不够详细,所以我做了谷歌搜索,了解了霍夫曼编码的过程。教科书声称在上面的代码末尾,生成了一个霍夫曼树。但对我来说,这似乎是错误的,因为霍夫曼树不一定是完整的树,但由于heap.push(),上面的代码似乎总是给出完整的树。那么有人可以向我解释这段代码如何没有错吗?

【问题讨论】:

    标签: c++ algorithm data-structures huffman-code


    【解决方案1】:

    堆的树结构不一定与生成的霍夫曼树匹配——相反,堆包含部分霍夫曼树的森林,最初每棵树都由一个符号节点组成。然后循环重复取两个权重最小的节点,将它们组合成一个节点,并将得到的组合节点放回原处。在进程结束时,堆包含一棵已完成的树。

    【讨论】:

    • 那么我不明白的是,如果堆不一定是霍夫曼树,我怎么能遍历或使用堆找到正确的叶节点。
    • 堆是一个临时的辅助数据结构,用来提高寻找两个Huffman节点权重最小的操作的效率。最后,堆只包含一个元素,单个BinaryTreeNode&lt;T&gt;,可以弹出,然后是完成的霍夫曼树的根;然后可以销毁堆,因为不再需要它。
    【解决方案2】:

    霍夫曼编码的工作原理是在每一步中取两个最低值的项目。当您第一次调用该函数时(因为您的 MinHeap 是按值排序的),两个最低值项目被弹出并“组合”到一个决策节点中,然后将其放回堆中。该节点根据其子节点得分的总和进行评分,然后放回堆中。将其重新插入堆中,根据其分数将其放入正确的位置;如果它仍然低于任何其他项目,它将是第一个,否则它将在其他地方。

    所以这个算法是自下而上构建树,当你清空堆时,你将拥有一棵完整的树。不过,我不明白“n”是什么意思。循环应该是while (heap.size() &gt; 1)。无论如何,树不是“满的”,不同的分支将有不同的长度,具体取决于初始堆中项目的频率。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多