博主自己手擼的代碼,若有有錯誤,感謝指出 直接上代碼
目錄
0.1 二元前綴碼 0.2 平均傳輸位數 0.3 僞碼 0.4 實例
0 講義
0.1 二元前綴碼
0.2 平均傳輸位數
0.3 僞碼
0.4 實例
代碼:生成哈夫曼樹&主函數
1 代碼
哈夫曼編碼是數據結構常考知識點,對比以前C寫的代碼,python真的簡單易懂。
1.1 哈夫曼編碼&計算平均位數
# 哈夫曼編碼, 計算平均位數
def huffmanCode(root, tree, rootCode='', codeDict={}, depth=1, res=0):
# 一般情況下 root = {'left': ['a', 45], 'right': ['cbfed', 55]}
# 對左子樹進行處理:如果是葉子節點,就打印編碼;否則遞歸
if len(root['left'][0]) == 1:
codeDict[root['left'][0]] = '0'+ rootCode
res += (len(rootCode)+1) * root['left'][1] # 計算平均位數
else:
codeDict, res = huffmanCode(tree[root['left'][0]], tree, '0'+rootCode, codeDict, depth+1, res)
# 對右子樹進行處理:如果是葉子節點,就打印編碼;否則遞歸
if len(root['right'][0]) == 1:
codeDict[root['right'][0]] = '1'+ rootCode
res += (len(rootCode)+1) * root['right'][1] # 計算平均位數
else:
codeDict, res = huffmanCode(tree[root['right'][0]], tree, '1'+rootCode, codeDict, depth+1, res)
return codeDict, res
1.2 生成哈夫曼樹&主函數
s = eval(input('若干字符:'))
w = eval(input('對應權重:'))
# 合併成一個字典
arr = [[s[i],w[i]] for i in range(len(s))]
# [['a', 45], ['b', 13], ['c', 12], ['d', 16], ['e', 9], ['f', 5]]
tree = {}
while len(arr)>1:
# 1 根據權重排序
arr.sort(key=lambda x:x[1])
# 2 選出最小的兩個節點,分別作爲左子樹,右子樹
l = arr[0] # 較小的作爲左子樹
r = arr[1] # 較大者作爲右子樹
if len(arr)>2:
tree[l[0]+r[0]] = {'left':l, 'right':r}
# 3 用新節點置換這兩個節點
arr = arr[2:]
arr.append([l[0]+r[0], l[1]+r[1]])
else:
tree['root'] = {'left':l, 'right':r}
break
print('\n哈夫曼樹:',tree)
code, res = huffmanCode(tree['root'], tree)
print('哈夫曼編碼:',code)
print('平均傳輸位數:',res/sum(w))
"""
若干字符:'a','b','c','d','e','f'
對應權重:45,13,12,16,9,5
哈夫曼樹: {
'fe': {'left': ['f', 5], 'right': ['e', 9]},
'cb': {'left': ['c', 12], 'right': ['b', 13]},
'fed': {'left': ['fe', 14], 'right': ['d', 16]},
'cbfed': {'left': ['cb', 25], 'right': ['fed', 30]},
'root': {'left': ['a', 45], 'right': ['cbfed', 55]}
}
哈夫曼編碼: {
'a': '0',
'c': '001',
'b': '101',
'f': '0011',
'e': '1011',
'd': '111'}
平均傳輸位數: 2.24
"""