【问题标题】:Size constraints on DEFLATE Huffman treesDEFLATE Huffman 树的大小限制
【发布时间】:2020-08-03 15:13:47
【问题描述】:
阅读 RFC 1951,似乎有效的动态霍夫曼树不一定是完整的二叉树 - 例如,由位长 (2, 2, 2) 指定的树有一个带有单个子节点的节点:
____
/ \
0 1
/ \ /
0 1 0
当尝试在一次分配中为整棵树分配足够的内存时,这会导致问题,因为任意二叉树中的节点数不一定有任何上限。
DEFLATE 标准中的约束是否意味着动态 Huffman 树的大小有上限?
【问题讨论】:
标签:
binary-tree
huffman-code
deflate
【解决方案1】:
RFC 1951 将“霍夫曼码”定义为在构建最佳前缀码时产生的内容。因此,在有效的放气流中使用的霍夫曼码必须是完整的,才能达到最优。您的示例不是,使用未使用的代码11。 1-2-2 代码将是完整的,没有未使用的代码。
RFC 1951 中的这条规则有一个例外,即单独的距离代码被编码为一位,而不是零位:
如果仅使用一个距离码,则使用一位编码,而不是
零位;在这种情况下,只有一个代码长度为 1,其中一个
未使用的代码。
zlib 的 inflate 拒绝任何带有无效 Huffman 代码的 deflate 流。
还有一个更微妙的地方,即 deflate 中的霍夫曼代码长度限制为 15 位,在代码的编码中强制执行。这并没有改变代码需要完整的事实。
对于一个完整的前缀码,内部节点的数量是n-1,其中n是编码的符号数。
由于长度限制的微妙性,即使对于非最佳前缀代码,节点的数量也会受到限制。最坏的情况是为所有符号分配最大位数。然后只需构建树并计算节点。你最终得到的是一个符号的平面代码树,它的基础连接到根,一行单个分支节点连接到根。所以实际上,由于规范代码的构造方式,节点数量并不多于最佳前缀代码。
例如,如果所有 30 个距离代码的长度均为 15,则规范树如下所示:
一个最佳前缀码不是 29 个内部节点,而是 40 个内部节点。