是的,这只是一种构建对码字长度有限制的霍夫曼代码的方法。
霍夫曼代码用可以唯一确定的二进制字符串对字母表中的每个字母进行编码。例如,如果您的字母表是 {A, B, C} 并且 A 比 B 和 C 更常见,则以下编码可以很好地工作:
A - 0
B - 10
C - 11
像 0010110 这样的编码字符串可以唯一编码,因为编码位字符串的长度已经由 Huffman 代码定义(这里 --- 每个以 0 开头的字符串的长度为 1,每个以 1 开头的字符串都有长度2)。所以字符串解码为 0|0|10|11|0 = AABCA。
现在构建霍夫曼码的“问题”是如何选择编码位串,以使生成的编码平均尽可能短。在您的问题中,还有一个额外的约束,即任何代码字的长度都不能超过L。一般的想法是使用较短的字符串来编码更常见的符号。
包合并算法的细节并不重要,因为关键是您使用一种算法来选择“一组面额总计为 n - 1 的最小钱币值的硬币”。如果您有面额为 2 −1、2 −2、...的硬币,并且您想从中建立 100 美分的总价值,您可以将此过程视为首先拥有价值 100 的硬币,然后拆分它变为两个 50 美分 (2 -1 ),然后继续将您的硬币分成两半,例如 50 美分 + 25 美分 + 12.5 美分 + 12.5 美分。这对应于二叉树的构造;每当您拆分硬币时,您都会在二叉树中创建一个内部节点,并在更深的一层添加两个叶子。
现在最小化钱币值的想法是那些与“更高频率”符号相关联的“硬币”使用起来更昂贵,因此您希望更少地分割这些硬币,对应于更短的代码。
细节留给读者作为练习。