【掃盲】---哈夫曼編碼&哈夫曼樹

以前學過的知識都沒啥印象了,再次記錄一下。

哈夫曼編碼(Huffman Coding),又稱霍夫曼編碼,是一種編碼方式,可變字長編碼(VLC)的一種。Huffman於1952年提出一種編碼方法,是一種統計編碼方式,屬於無損壓縮編碼。哈夫曼編碼是變長編碼,對於出現頻率高的信息,編碼長度較短,出現頻率低的信息,編碼長度較長。這樣處理全部信息的總碼長一定小於實際信息的符號長度。有時稱之爲最佳編碼,一般就叫做Huffman編碼(有時也稱爲霍夫曼編碼)。

哈夫曼編碼,主要目的是根據使用頻率來最大化節省字符(編碼)的存儲空間。

比如我們有一段文字“BADCADFEED”,顯然用二進制數字(0和1)表示是很自然的想法。

這樣真正傳輸的數據就是“001000011010000011101100100011”,對方接收時同樣按照3位一組解碼。如果一篇文章很長,這樣的二進制串也非常的可怕。而且事實上,每個字母或者漢子的出現頻率是不同的。

å¾ç¤º

假設六個字母的頻率爲A 27,B 8, C 15, D 15 , E 30, F 5,合起來正好是100%,那就意味着我們完全可以用哈夫曼樹來規劃它們。

左圖爲構造哈夫曼樹的過程的權值顯示。右圖爲將權值左分支改爲0,右分支改爲1後的哈夫曼樹。

å¾ç¤º

我們對這六個字母用其從樹根到葉子所經過的路徑的0或1來編碼,可以得到下表:

å¾ç¤º

å¾ç¤º

也就是說我們的數據被壓縮了,節約了大概17%的存儲或傳輸成本。隨着字符的增加和多字符權重的不同,這種壓縮會更顯出優勢來。

接收到哈夫曼編碼後應該如何解碼呢?
仔細觀察上面的赫夫曼編碼表中各個字母的編碼會發現,不存在容易與1001、1000混淆的10、100等編碼。這就說明若要設計長短不等的編碼,則必須是任一字符的編碼都不是另一個字符的編碼的前綴,這種編碼稱作前綴編碼

可僅僅是這樣不足以讓我們去方便的解碼,因此解碼時,還是要用到哈夫曼樹,即發送方和接收方必須約定好同樣的哈夫曼編碼規則。

 


哈夫曼編碼步驟:

①概率統計(如對一幅圖像或者m幅同種類型圖像作灰度統計),得到n個不同概率的信息符號;

②將信號源的符號按照出現概率遞減的順序排列;

③在信源符號中選擇概率最小的兩個,將他們的概率相加,計算結果作爲其合事件(新符號)的出現概率。在合併運算時,概率大的符號用編碼0表示,概率小的符號用編碼1表示;

④這時概率的個數減爲n-1個,將這n-1個概率,按從大到小的順序排序;

⑤重複③,將新排序後的最後兩個小概率再相加,計算合事件的概率,如此反覆重複n-1次,只帶概率相加的結果爲1爲止;

⑥記錄下概率爲1處到當前信號源符號之間的0,1序列,從而得到每個符號的編碼,構成霍夫曼碼字,到此編碼結束。

 

簡易的理解就是,假如我有A,B,C,D,E五個字符,出現的頻率(即權值)分別爲5,4,3,2,1,那麼我們第一步先取兩個最小權值作爲左右子樹構造一個新樹,即取1,2構成新樹,其結點爲1+2=3,權重大的符號用1表示,權重小的符號用0表示,如圖:

è¿éåå¾çæè¿°

虛線爲新生成的結點,第二步再把新生成的權值爲3的結點放到剩下的集合中,所以集合變成{5,4,3,3},再根據第二步,取最小的兩個權值構成新樹,如圖: 

è¿éåå¾çæè¿°


再依次建立哈夫曼樹,如下圖:

è¿éåå¾çæè¿°

其中各個權值替換對應的字符即爲下圖:

è¿éåå¾çæè¿°

所以各字符對應的編碼爲:A->11,B->10,C->00,D->011,E->010 


霍夫曼編碼是一種無前綴編碼。解碼時不會混淆。其主要應用在數據壓縮,加密解密等場合。

如果考慮到進一步節省存儲空間,就應該將出現概率大(佔比多)的字符用盡量少的0-1進行編碼,也就是更靠近根(節點少),這也就是最優二叉樹-哈夫曼樹。

哈夫曼樹

哈夫曼樹又稱最優二叉樹,是一種帶權路徑長度最短的二叉樹。所謂樹的帶權路徑長度,就是樹中所有的葉結點的權值乘上其到根結點的路徑長度(若根結點爲0層,葉結點到根結點的路徑長度爲葉結點的層數)。樹的帶權路徑長度記爲WPL=(W1*L1+W2*L2+W3*L3+…+ Wn*Ln),N個權值Wi(i=1,2,…n)構成一棵有N個葉結點的二叉樹,相應的葉結點的路徑長度爲Li(i=1,2,…n)。可以證明哈夫曼樹的WPL是最小的。 
構造哈夫曼樹的算法如下: 
1)對給定的n個權值{W1,W2,W3,…,Wi,…,Wn}構成n棵二叉樹的初始集合F={T1,T2,T3,…,Ti,…, Tn},其中每棵二叉樹Ti中只有一個權值爲Wi的根結點,它的左右子樹均爲空。 
2)在F中選取兩棵根結點權值最小的樹作爲新構造的二叉樹的左右子樹,新二叉樹的根結點的權值爲其左右子樹的根結點的權值之和。 
3)從F中刪除這兩棵樹,並把這棵新的二叉樹同樣以升序排列加入到集合F中。 
4)重複2)和3),直到集合F中只有一棵二叉樹爲止。

哈夫曼樹的應用場景


其實赫夫曼樹使用場景還真不少,例如apache負載均衡的按權重請求策略的底層算法、咱們生活中的路由器的路由算法、利用哈夫曼樹實現漢字點陣字形的壓縮存儲

 

參考:

https://blog.csdn.net/qq_36653505/article/details/81701181

https://blog.csdn.net/u011507175/article/details/64920643

https://blog.csdn.net/qq_28602957/article/details/71036402

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