【算法】貪心算法 哈夫曼編碼 python

博主自己手擼的代碼,若有有錯誤,感謝指出  直接上代碼

目錄

0 講義

0.1 二元前綴碼   0.2 平均傳輸位數     0.3 僞碼    0.4 實例

1 代碼


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
"""

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章