给定N个权值作为N个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。
#结点类
class Node():
def __init__(self,name=None,value=None):
self.name = name
self.value = value
self.left = None
self.right = None
#哈夫曼树类
class HuffmanTree():
def __init__(self,char_weight):
self.leaf = [Node(part[0],part[1]) for part in char_weight] #将叶子结点都放入一个列表
while len(self.leaf)!=1:
self.leaf.sort(key=lambda node:node.value,reverse=True) #从大到小排序
c=Node(value=(self.leaf[-1].value+self.leaf[-2].value)) #建立一个新结点
c.left=self.leaf.pop(-1) #建立左孩子,并删除
c.right=self.leaf.pop(-1) #建立右孩子,并删除
self.leaf.append(c) #加入这个结点
self.root = self.leaf[0]
self.code = list(range(10)) #存放编码,只需比最大长度大即可
# 生成编码,并输出
def set_code(self,tree,length):
node=tree
if(not node):
return None
elif node.name:
print(node.name + '的编码为:',end=" ")
for i in range(length):
print(self.code[i],end="")
print('\n')
return None
self.code[length]=0 #左孩子编码为0
self.set_code(node.left,length+1) #递归调用
self.code[length]=1 #右孩子编码为1
self.set_code(node.right,length+1) #递归调用
# 获取编码
def get_code(self):
self.set_code(self.root,0)
import random
if __name__ == "__main__":
char = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n']
char_weights = []
n = int(input("请输入长度"))
# weight = [int(i) for i in input().split()] # 通过键盘输入
weight = [random.randint(0,100) for _ in range(n)]
for i in range(n):
char_weights.append((char[i],weight[i]))
tree = HuffmanTree(char_weights)
tree.get_code()