哈夫曼樹,及哈夫曼編碼的構造
最近看到騰訊一個關於哈夫曼編碼的題目(如下)
某段文字中各個字母出現的頻率分別是{a:4,b:3,o:12,h:7,i:10},使用哈夫曼編碼,則哪種是可能的編碼:()
- a(000) b(001) h(01) i(10) o(11)
- a(0000) b(0001) h(001) o(01) i(1)
- a(000) b(001) h(01) i(10) o(00)
- a(0000) b(0001) h(001) o(000) i(1)
本來開始覺得很簡單(因為之前有學過這方面的問題)
結果一頭霧水,用了下百度神器。果然奏效。
為了防止日後有忘記,故寫文件加以儲存
首先:建立一個哈夫曼樹
原則如下:
1. 將每個英文字母依照出現頻率由小排到大,最小在左,組成一個序列
2. 每個字母都代表一個終端節點(葉節點),比較每個字母的出現頻率,將最小的兩個字母頻率相加合成一個新的節點,將兩個字母從序列中刪除,將生成的節點加入到字母佇列中
3. 重複前面兩步,直到序列中沒有字母為止
進行編碼:
1. 給霍夫曼樹的所有左鏈結'0'與右鏈結'1'
2. 從樹根至樹葉依序記錄所有字母的編碼
好:我們先來構造
v = {b(3),a(4),h(7),i(10),o(12)}
取最小兩個權值構成一棵樹(如下)
--------(7)
---------/---\
-------/------\
-----b(3)---a(4)
然後將(7)加入序列:(7),h(7),i(10),o(12)
再取最小兩個權值構成樹:如下
-----------------(14)
--------------/--------\
------------/------------\
--------(7)---------h(7)
---------/---\
-------/------\
-----b(3)---a(4)
將(14)加入權值序列:(14),i(10),o(12)現在取10跟12構成一顆新數:如下
----------------(14)------------------(22)
--------------/--------\----------------/-----\
------------/------------\ -----------/----------\
--------(7)---------h(7) ---i(10)--------o(12)
---------/---\
-------/------\
-----b(3)---a(4)
最好權值相加:--------------------------(36)
--------------------/-----------------\
------------------/---------------------\
----------------(14)------------------(22)
--------------/--------\----------------/-----\
------------/------------\ -----------/----------\
--------(7)---------h(7) ---i(10)--------o(12)
---------/---\
-------/------\
-----b(3)---a(4)
現在執行哈夫曼編碼:從第二個接點開始:進行編碼:
1. 給霍夫曼樹的所有左鏈結'0'與右鏈結'1'
2. 從樹根至樹葉依序記錄所有字母的編碼
--------------------------(36)
--------------------/-----------------\
------------------/---------------------\
----------------0(14)------------------1(22)
--------------/--------\----------------/-----\
------------/------------\ -----------/----------\
--------0(7)---------1h(7) ---0i(10)--------1o(12)
---------/---\
-------/------\
-----0b(3)---1a(4)
結果:a:001,b000,h01,i10,o11
答案a