【问题标题】:Efficient Huffman tree search while remembering path taken在记住路径的同时进行高效的霍夫曼树搜索
【发布时间】:2009-04-30 16:53:38
【问题描述】:

作为与我的question regarding efficient way of storing huffman tree's 相关的后续问题,我想知道搜索二叉树(基于 Huffman 编码输出)并存储通向特定节点的路径的最快和最有效的方法是什么。

这是我目前拥有的:

  • 将根节点添加到队列中
  • 当队列不为空时,将项目从队列中弹出
    • 检查它是否是我们正在寻找的
      • 是的: 跟随一个头指针回到根节点,同时在每个节点上我们访问检查它是左还是右并记下它。
      • 跳出搜索
    • 将左右节点加入队列

由于这是一棵 Huffman 树,因此我要查找的所有条目都将存在。以上是广度优先搜索,这被认为是霍夫曼树的最佳选择,因为源中的项目更频繁地在树中较高以获得更好的压缩,但是我无法找到跟踪的好方法我们如何使用我放在节点中的头指针不回溯就到达特定节点。

在这种情况下,我还以相反的顺序获取所有右/左路径,例如,如果我们从头到根,我们发现从根开始它是右、左、左,我们左,左,右。或二进制的 001,而我正在寻找的是以有效的方式获得 100。

还建议将从根到节点的路径存储为节点内的单独值,但是如果我们有一个大于我们为此目的创建的变量可以容纳的位数的树,这将崩溃,那时存储数据也会占用大量内存。

【问题讨论】:

  • 关于存储位串,不能用vector来存储位串吗?它紧凑地存储位,并且可以存储任意数量的位。
  • "而此时存储数据也会占用大量内存。"通常霍夫曼编码用于编码字节(技术上,来自某些字母表的符号)。那么它怎么能变大呢?只有 256 个可能的字节。
  • @newacct:当然可以,但是 vector 每个 bool 占用 1 个字节, std::bitset 会更好。你提出了一个很好的观点,如果使用字节,只有 256 个,我们有另一个分配,因为它从磁盘读取 int,留下 2^32 个可能的选项,此时内存需求变得非常大,因此我的问题是关于最快的方法从已经存在的二叉树中检索路径。
  • 关于向量,实际上没有。 vector 每 8 个布尔值占用 1 个字节。并且 bitset 不起作用,因为它的大小必须在编译时固定,而在运行时每个符号的位串必须是不同的长度。由于您的霍夫曼树适合内存,因此我假设编码中使用的实际符号数量少于 2^32。在这种情况下,您应该能够使用某种 trie,它占用的内存与条目数成正比。

标签: c++ performance huffman-code


【解决方案1】:

创建一个值字典 -> 位串,这将为您提供最快的查找。

如果这些值的大小是已知的,您可能只需要一个位字符串数组并通过它们的索引查找值。

【讨论】:

  • 这仍然存在必须存储位串的问题,现在我们将其从将位串存储在叶节点中移动到字典,具有基本相同的内存权衡.
  • 但是您确实要求最快的方式,不是吗?
  • 当然,我确实做到了,但我专门要求一棵二叉树。不允许预先计算结果,因为我在问题的最后一段中特别排除了它。
【解决方案2】:

如果您一次一位地解码 Huffman 编码的数据,您的性能会很差。尽管您想避免使用查找表,但如果您关心性能,这是唯一的方法。霍夫曼代码的创建方式从左到右是唯一的,非常适合快速查找表。

【讨论】:

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