霍夫曼编码树遍历
Huffman Coding Tree traversal
在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}
每个字母 if 然后转换为 HuffNode
并存储在 Nodes
然后 while
循环继续生成一棵树,直到我们只有一个根
When the loop exits I'll have:
遍历这棵树然后为每个字母生成代码的最佳方法是什么?
谢谢
一般来说,您需要一个递归函数,给定 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
)是管理不平衡的节点,其中一个children可能是空的。
在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}
每个字母 if 然后转换为 HuffNode
并存储在 Nodes
然后 while
循环继续生成一棵树,直到我们只有一个根
When the loop exits I'll have: 遍历这棵树然后为每个字母生成代码的最佳方法是什么? 谢谢
一般来说,您需要一个递归函数,给定 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
)是管理不平衡的节点,其中一个children可能是空的。