每天一個算法——霍夫曼編碼壓縮算法

程序員 科技 極客碼農 2017-04-26

算法是自己作為程序員開發比較薄弱的地方,之前大學的時候也沒有好好學,工作中具體用到的也很少。但我深知算法是程序員這個行業,真正有意義的地方,搬磚似得碼農到處都有,但如果你會點算法,可能一次可以搬兩塊磚也說不定。所以,我決定今天起,開始認真整理和算法相關的一些東西,作為自己的一點成長,一點積累。也歡迎大家關注我,一起討論,一起進步。


霍夫曼編碼壓縮算法,是數據壓縮中經典的一種算法。這是一種根據文本字符出現的頻率,重新對字符進行編碼,頻率越高的詞,編碼越短,從而達到數據壓縮的效果。

假設我們有這樣的一段數據需要進行編碼——“beep boop beer!”。這段字符通過ASCII編碼後的結果為62 65 65 70 20 62 6F 6F 70 20 62 65 65 72 21 (十六進制),總共有十五個字節。

每天一個算法——霍夫曼編碼壓縮算法

首先,我們先計算每個字符出現的頻率,經過我們統計,得到下面一張表:

每天一個算法——霍夫曼編碼壓縮算法

然後把這些數放到優先級隊列中,從左到右,頻率逐漸增加。

每天一個算法——霍夫曼編碼壓縮算法

下面我們需要把這個隊列,轉換成霍夫曼二叉樹,這是一個帶有權重的二叉樹,在隊列中每個字符出現的次數,標識這個字符的權重,霍夫曼二叉樹始終保證權重高的在越高的地方。下面來介紹,二叉樹是如何演變的。

我們從最左邊開始,取兩個元素來構造一個二叉樹(第一個元素是左結點,第二個是右結點),並把這兩個元素的權重相加,得到新的空元素。

每天一個算法——霍夫曼編碼壓縮算法

同理,我們繼續取最左邊兩個元素,進行權重相加(2+2=4),相加結果變大,需要對權重進行重新排序。

每天一個算法——霍夫曼編碼壓縮算法

繼續執行同樣的操作,這裡可以看到自底向上的構建二叉樹的一個過程。

每天一個算法——霍夫曼編碼壓縮算法

每天一個算法——霍夫曼編碼壓縮算法

最後,我們得到這樣一個帶有權重的二叉樹:

每天一個算法——霍夫曼編碼壓縮算法

這裡,我們把這個樹的左邊分支用0編碼,右邊分支用1,這樣我們就可以遍歷這棵二叉樹獲取每個字符的編碼,例如:‘b’的編碼是 00,’p’的編碼是101, ‘r’的編碼是1000。我們可以發現出現次數越多的字符會越在上層,它的編碼也越短,次數少的字符,編碼越長

每天一個算法——霍夫曼編碼壓縮算法

最後我們可以得到下面這張編碼表:

每天一個算法——霍夫曼編碼壓縮算法

利用這個編碼表我們對字符串“beep boop beer!”重新進行編碼,得到:0011 1110 1011 0001 0010 1010 1100 1111 1000 1001。共計40位二進制,而之前沒重新編碼時,是15字節共120位,這樣看來壓縮比例還是比較客觀的。

相關推薦

推薦中...