霍夫曼编码树遍历

时间:2017-10-19 08:45:12

标签: python algorithm compression huffman-code

在Python中编写霍夫曼编码算法。已经成功地设法根据字符串输入创建了一个树,但是在生成每个字母的代码时,我仍然坚持最佳的遍历方式。

from collections import Counter
    class HuffNode:
        def __init__(self, count, letter=None):
            self.letter = letter
            self.count = count
            self.right = None
            self.left = None

    word = input()
    d = dict(Counter(word))

    Nodes = [HuffNode(d[w], w) for w in sorted(d, key=d.get, reverse=True)]

    while len(Nodes) > 1:
        a = Nodes.pop()
        b = Nodes.pop()
        c = HuffNode(a.count+b.count)
        c.left, c.right = a, b

        Nodes.append(c)
        Nodes.sort(key=lambda x: x.count, reverse=True)

对于像" hello"。

这样的词

d = dict(Counter(word))将获得字符串中每个字母的频率并将其转换为字典。因此,{'e': 1, 'l': 2, 'h': 1, 'o': 1}每个字母如果转换为HuffNode并存储在Nodes

然后while循环继续生成树,直到我们只有一个根

When the loop exits I'll have: 什么是遍历这棵树然后为每个字母生成代码的最佳方法? 感谢

1 个答案:

答案 0 :(得分:0)

一般来说,你需要一个递归函数,给定HuffNode h和前缀p:

  • 如果h.letter不为空(即h是叶子),则产生(p, h.letter) - >这是信件的代码
  • 否则,在h.left上使用前缀p + '0'并在h.right上使用p + '1'
  • 调用自身

可能的实施(未经测试,可能有错别字):

def make_code(node, prefix):
    if node is None:
        return []
    if node.letter is not None:
        return [(prefix, node.letter)]
    else:
        result = []
        result.extend(make_code(h.left, prefix + '0'))
        result.extend(make_code(h.right, prefix + '1'))
        return result

codes = make_code(root, '')

其中root是您在第一步中构建的霍夫曼树。第一个测试(if node is None)是管理不平衡的节点,其中一个孩子可能是空的。