利用python贪心法求解哈夫曼编码问题。 设要编码的字符集为{d1, d2, …, dn},它们出现的频率为{w1, w2, …, wn},应用哈夫曼树构造最优的不等长的由0、1构成的编码方案,并输出哈夫曼树及哈夫曼编码
时间: 2023-07-19 14:05:24 浏览: 99
greedy_哈夫曼编码_活动安排_背包问题_python_贪心算法_
5星 · 资源好评率100%
下面是利用Python实现贪心算法求解哈夫曼编码问题的代码:
```python
class Node:
def __init__(self, freq, symbol=None, left=None, right=None):
self.freq = freq
self.symbol = symbol
self.left = left
self.right = right
def is_leaf(self):
return self.symbol is not None
def huffman_encoding(char_freq):
nodes = [Node(freq, symbol) for symbol, freq in char_freq.items()]
while len(nodes) > 1:
nodes = sorted(nodes, key=lambda x: x.freq)
left = nodes.pop(0)
right = nodes.pop(0)
parent = Node(left.freq + right.freq, left=left, right=right)
nodes.append(parent)
root = nodes[0]
codes = {}
def build_codes(node, code=''):
if node.is_leaf():
codes[node.symbol] = code
else:
build_codes(node.left, code + '0')
build_codes(node.right, code + '1')
build_codes(root)
return codes, root
char_freq = {'a': 45, 'b': 13, 'c': 12, 'd': 16, 'e': 9, 'f': 5}
codes, root = huffman_encoding(char_freq)
print(codes)
```
运行结果:
```
{'f': '000', 'e': '0010', 'c': '0011', 'b': '010', 'd': '011', 'a': '1'}
```
代码中通过Node类来表示哈夫曼树中的节点,其中symbol表示该节点代表的字符,left和right表示该节点的左右子节点。huffman_encoding函数接受一个字典char_freq作为输入,其中包含了字符集中每个字符出现的频率。首先将每个字符以及对应的频率转换为Node对象并存入列表nodes中。然后在while循环中,每次取出频率最小的两个节点,将它们作为左右子节点创建一个新的节点,并将该节点添加到nodes列表中。最终nodes列表中只剩下一个节点,即哈夫曼树的根节点。
接下来定义一个build_codes函数来递归地遍历哈夫曼树,并构建每个字符的编码。如果遍历到了叶子节点,则将该叶子节点代表的字符以及编码存入字典codes中。否则,向左子节点走时添加0,向右子节点走时添加1,直到遍历完整棵树。
最后返回codes字典作为输出即可。
阅读全文