本程式主要使用霍夫曼編碼對任意檔案進行壓縮。
程式的步驟如下:
如果有一個檔案大小為8個bytes。
其中ascii為m的字元一共出現了n次:
m n
1 3
2 2
3 1
4 1
5 1
以n的大小為依據構建霍夫曼樹:
如果將父節點通往左孩子的路徑標識為0,通往右孩子的路徑標識為1,則霍夫曼樹變成如下:
則出現n次的字元所對應的的編碼為p:
n p
3 1
2 01
1 001
1 0001
1 0000
最終該檔案的霍夫曼編碼為:
1 1 01 001 0001 01 0000 1
以8個bit為一個byte寫入檔案。
第一個byte:11010010
第二個byte:00101000
第三個byte:01000000 (最後6位補0)
可見8個自己最後壓縮為3個位元組。
在解壓的時候要需要霍夫曼樹,而霍夫曼樹要由原始檔案每個位元組出現的個數來構建,
所以在壓縮檔中還要寫入每個位元組出現的個數。因為1個byte最多表示256個數,所以int table[256]
來存放byte出現的次數,如果讀到一個byte,則將table[byte]++。
構建出霍夫曼樹後,就要根據霍夫曼編碼進行解碼,
1 1 01 001 0001 01 0000 1000000
如上編碼的解碼過程如下:
第1個為1,則指向根節點的右孩子,到達末節點,寫入該節點對應的字元(ascii為1)。
......依次類推
寫完原檔案大小x個位元組,則停止寫入,所以原檔案的大小也要被記錄到壓縮檔中。
所以最終的壓縮檔結構如下:
原始碼(linux c):
http://f.xunlei.com/7454406/file/10e751ae-5b52-4cf8-a66a-59d5bef4886f
壓縮檔:
hfm -c filename
產生的壓縮檔為filename.hfm
解壓檔案:
hfm -d filename.hfm
還原成檔案filename
最後:
這種演算法只能對一些檔案具有壓縮效果,對某些檔案可能出現壓縮檔比原檔案還大的現象。
本程式也只是初略地瞭解下該演算法在檔案壓縮方面的應用,如有其它改進的地方,請大家多多指點。謝謝~