【算法】贪心算法 哈夫曼编码 python

博主自己手撸的代码,若有有错误,感谢指出  直接上代码

目录

0 讲义

0.1 二元前缀码   0.2 平均传输位数     0.3 伪码    0.4 实例

1 代码


0 讲义

0.1 二元前缀码

 【算法】贪心算法 哈夫曼编码 python_第1张图片

0.2 平均传输位数

代码:计算平均位数

【算法】贪心算法 哈夫曼编码 python_第2张图片

0.3 伪码

代码:哈夫曼编码

【算法】贪心算法 哈夫曼编码 python_第3张图片

0.4 实例

代码:生成哈夫曼树&主函数

【算法】贪心算法 哈夫曼编码 python_第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
"""

 

你可能感兴趣的:(小分类,python,数据结构,贪心算法,哈夫曼编码)