哈夫曼編碼(Huffman Coding)原理、運行步驟、python實現

哈夫曼編碼是貪心算法的一個典型應用。哈夫曼編碼利用每條數據出現的頻率(概率),從信息論的角度出發,將這些數據重新編碼。哈夫曼編碼的編碼結果是給出現頻率較高的數據一個較短的編碼,給出現頻率較低的數據一個較長的編碼。

讓我們舉個例子說明一下哈夫曼編碼的步驟:現在有數據[a,a,a,a,a,b,b,b,b,c,c,c,d,d,e]。可以看出字符a出現了5次,字符2出現了4次,字符c出現了3次,字符d出現了2次,字符e出現了1次。

首先,我們將這5個字符看成一個森林,它們的值是它們出現的頻率,我們首先要做的是把這些森林合併成一棵哈夫曼樹。利用貪心算法合併每個節點。

合併算法:先選取兩個根節點頻率值最小的森林,將這兩個森林作合併爲一棵樹,其根節點的值爲上述兩個根節點頻率值的和,上述兩個根節點爲新樹根節點的左右節點。重複合併步驟,直到將所有森林合併成一棵樹算法終止。算法過程如下圖:

步驟 狀態
init 在這裏插入圖片描述
1 在這裏插入圖片描述
2 在這裏插入圖片描述
3 在這裏插入圖片描述
4 在這裏插入圖片描述

構造完哈夫曼樹之後,按照遍歷路徑來獲得每個字符的編碼即可:

在這裏插入圖片描述

編碼結果如下表:

字符 編碼
a 00
b 01
c 10
d 110
e 111

附上python代碼實現:

"""
@filename   [huffman.py]
@author     [zxy]
@version    [v1.0]
@date       [2020/3/13]
"""

import queue
class Node:
    def __init__(self, x, k=-1, l=None, r=None, c=''):
        self.freq = x
        self.key = k
        self.left = l
        self.right = r
        self.code = c
    def __lt__(self, otr):
        return self.freq < otr.freq

def huffman_code(data):
    freqTable={}
    nodeList=[]
    que=queue.PriorityQueue()
    codeTable={}
    
    # frequent label init
    for n in data:
        if n in freqTable:
            freqTable[n]+=1
        else:
            freqTable[n]=1
    
    # Huffman tree init
    for k,v in freqTable.items():
        nodeList.append(Node(v,k))
        que.put(nodeList[-1])
        
    # Huffman tree generate
    while que.qsize()>1:
        n1=que.get()
        n2=que.get()
        n1.code='1'
        n2.code='0'
        nn=Node(n1.freq+n2.freq,l=n1,r=n2);
        nodeList.append(nn);
        que.put(nodeList[-1])

    # get Huffman code
    def bl(p,codestr=[]):
        codestr.append(p.code)
        if p.left:
            bl(p.left,codestr.copy())
            bl(p.right,codestr.copy())
        else:
            codeTable[p.key]=''.join(codestr)
    bl(nodeList[-1])
    
    # print Huffman code result
    print(str(codeTable))
    
    return codeTable
    
    
if __name__ == '__main__':
    data=[1,1,1,1,1,2,2,2,2,3,3,3,4,4,5]
    huffman_code(data)
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章