生成树
from heapq import heapify, heappush, heappop
from itertools import count
"""
https://www.cnblogs.com/xuchunlin/p/7247346.html
"""
def huffman(nodes, frequent):
num = count()
trees = list(zip(frequent, num, nodes)) # num ensures valid ordering
heapify(trees) # A min-heap based on freq
while len(trees) > 1: # Until all are combined
value1, _, node1 = heappop(trees) # Get the two smallest trees
value2, _, node2 = heappop(trees)
heappush(trees, (value1 + value2, next(num), [node1, node2])) # Combine and re-add them
# print trees
return trees[0][-1]
if __name__ == \'__main__\':
chars = "fecbda"
weights = [5, 9, 12, 13, 16, 45]
print(huffman(chars, weights)) # [\'a\', [[\'c\', \'b\'], [[\'f\', \'e\'], \'d\']]]
编码
class Node:
def __init__(self, freq):
self.left = None
self.right = None
self.father = None
self.freq = freq
def isLeft(self):
return self.father.left == self
# create Huffman-Tree创建Huffman树
def createHuffmanTree(nodes):
queue = nodes[:]
while len(queue) > 1:
queue.sort(key=lambda item: item.freq)
node_left = queue.pop(0)
node_right = queue.pop(0)
node_father = Node(node_left.freq + node_right.freq)
node_father.left = node_left
node_father.right = node_right
node_left.father = node_father
node_right.father = node_father
queue.append(node_father)
queue[0].father = None
return queue[0]
# Huffman编码
def huffmanEncoding(nodes, root):
codes = [\'\'] * len(nodes)
for i in range(len(nodes)):
node_tmp = nodes[i]
while node_tmp != root:
if node_tmp.isLeft():
codes[i] = \'0\' + codes[i]
else:
codes[i] = \'1\' + codes[i]
node_tmp = node_tmp.father
return codes
if __name__ == \'__main__\':
chars = [\'A\', \'B\', \'C\', \'D\', \'E\', \'F\', \'G\', \'H\', \'I\', \'J\', \'K\', \'L\', \'M\', \'N\']
freqs = [10, 4, 2, 5, 3, 4, 2, 6, 4, 4, 3, 7, 9, 6]
chars_freqs = zip(chars, freqs)
chars_freqs = sorted(chars_freqs, key=lambda item: item[1])
nodes = [Node(item[1]) for item in chars_freqs]
root = createHuffmanTree(nodes)
encoding_map = huffmanEncoding(nodes, root)
for item in zip(chars_freqs, encoding_map):
print(\'Character:%s freq:%-2d encoding: %s\' % (item[0][0], item[0][1], item[1]))
复制
- 详细图解哈夫曼Huffman编码树
- 哈夫曼(huffman)树和哈夫曼编码
- Python 算法(2) 哈夫曼编码 Huffman Encoding