1. 程式人生 > >哈夫曼樹的構建、編碼以及帶權路徑長計算

哈夫曼樹的構建、編碼以及帶權路徑長計算

給定n個權值作為n個葉子結點,構造一棵二叉樹,若該樹的帶權路徑長度達到最小,稱這樣的二叉樹為最優二叉樹,也稱為哈夫曼樹(Huffman Tree)。哈夫曼樹是帶權路徑長度最短的樹,權值較大的結點離根較近。

構造哈夫曼樹的演算法如下:
        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中只有一棵二叉樹為止。

假設給定a、b、c、d、e、f的權值分別為{9, 12, 6, 3, 5, 15},構造哈夫曼樹的過程如下:

1、為了方便起見,首先將權值進行從小到大排序即,3, 5, 6, 9,12,15

2、選取最小的兩個權值3和5構建子樹。3+5 = 8作為3,5的父節點(我們規定要滿足左子節點小於右子節點)

3、順序提取6作為左子節點,8作為右子節點。將6+8 = 14作為其父節點。

4、我們發現14大於接下來的9,12。故將9,12作為子節點,9+12 = 21為其父節點構建一個子樹。提取元素15,作為右節點上一步構建的14作為左節點,將14+15 = 29作為他們的父節點構建另一個子樹。

5、最後將上述兩個子樹的父節點21,29分別作為左節點和右節點。將21+29 = 50作為他們的父節點。這樣就構造出了一個哈夫曼樹。

接下來進行帶權路徑長的計算:

a,b,f(權值9,12,15)三個元素距父節點的距離都為2

c(權值6)元素距父節點的距離為3

d,e(權值3,5)元素距父節點的距離為4

故這棵哈夫曼樹的WPL為:WPL =(9 + 12 + 15)*2 + 6 * 3 + (3 + 5)* 4 = 122

 

哈夫曼編碼

根據哈夫曼樹可以解決報文編碼問題。假設需要一個字串“aaaabbbbccccdddeeeeffffaaaabbbbcceffffabbbbfffffff”進行編碼,將它轉換為唯一的二進位制碼,但要求轉換出來的二進位制編碼的長度最小。

該字串中正好滿足a、b、c、d、e、f分別出現9, 12, 6, 3, 5, 15次,作為他們的權值。按照上述方法構建好哈夫曼樹。

從哈夫曼樹根節點開始,對左子樹分配程式碼“0”,對右子樹分配“1”,一直到達葉子節點。然後,將從樹根沿著每條路徑到達葉子節點的程式碼排列起來,便得到每個葉子節點的哈夫曼編碼,如下右圖。

從圖中可以看出:

a 的編碼為:00

b 的編碼為:01

c 的編碼為:100

d 的編碼為:1010

e 的編碼為:1011

f 的編碼為:11

 

參考:https://www.cnblogs.com/luankun0214/p/4423648.html?utm_source=tuicool&utm_medium=referral

           https://blog.csdn.net/move_now/article/details/53398753