'''
Huffman编码
根据每个字母出现的频率,构造二叉树,写出对应的字母的编码
'''
import queue
import heapq
#构造节点类(频率,字符,左儿子,右儿子,编码)
class node:
def __init__(self, f = None, char = None, left = None, right = None, code = None):
self.f = f
self.char = char
self.left = left
self.right = right
self.code = code
def __lt__(self, other):
return self.f < other.f
#构造二叉树
class Heap:
def __init__(self):
self._queue = []
def push(self, priorty, item):
heapq.heappush(self._queue, (priorty, item))
def pop(self):
if self._queue:
return heapq.heappop(self._queue)[-1]
else:
return None
#Huffman编码
def Huffman(C):
n = len(C)
q = Heap()
#将每个字母的单独成树,后面再合并
for i in range(n):
q.push(C[i], node(C[i], chr(97+i)))
#合并,比较
for i in range(n-1):
x = q.pop()
y = q.pop()
z = node(x.f+y.f, None, x, y, None)
q.push(x.f+y.f, z)
return q.pop()
#对排好序的二叉树进行编码
def Traceback(root, code):
if root == None:
return
root.code = code
Traceback(root.left, code+'0')
Traceback(root.right, code+'1')
#打印编码
def Print(root,n):
q = queue.Queue()
q.put(root)
l = {}
while not q.empty():
node = q.get()
if node.char:
# print(node.char, node.code)
l[node.char] = node.code
if node.left:
q.put(node.left)
if node.right:
q.put(node.right)
#按照字母顺序输出
for j in range(n):
for i in l.keys():
if i == chr(97+j):
print(i, l[i])
C = [45, 13, 12, 16, 9, 5]
root = Huffman(C)
Traceback(root, '')
Print(root, len(C))
输出样例:
a 0
b 101
c 100
d 111
e 1101
f 1100
如果不按照字母顺序输出则把有关字典l 的代码序列去掉即可
只需要稍微改动打印代码
def Print(root): q = queue.Queue() q.put(root) while not q.empty(): node = q.get() if node.char: print(node.char, node.code) if node.left: q.put(node.left) if node.right: q.put(node.right)