基於哈夫曼(haffuman)算法的文件壓縮的實現(C語言)(轉改)


       哈夫曼算法的主要思想是:

              ①首先遍歷要處理的字符串,得到每個字符的出現的次數;

              ②將每個字符(以其出現次數為權值)分別構造為二叉樹(注意此時的二叉樹只有一個節點);

              ③取所有二叉樹種種字符出現次數最小的二叉樹合並為一顆新的二叉樹,新二叉樹根節點的權值等於兩個子節點的權值之和,新節點中的字符忽略;

              ④重復過程③直到所有樹被合並為同一棵二叉樹

              ⑤遍歷最后得到的二叉樹,自頂向下按路徑編號,指向左節點的邊編號0,指向右節點的邊編號1,從根到葉節點的所有邊上的0和1鏈接起來,就是葉子節點中字符的哈夫曼編碼。

下圖展示了哈夫曼編碼的基本思想。


                                           

       基於哈夫曼算法的文件壓縮和解壓縮過程分別說明如下:

一、文件壓縮:

①統計詞頻:讀取文件的每個字節,使用整數數組int statistic[MAX_CHARS]統計每個字符出現的次數,由於一個字節最多表示2^8-1個字符,所以MAX_CHARS=256就足夠了。在統計字符數的時候,對     於每一個byte, 有statistic[(unsigned char)byte]++。

②構造哈夫曼樹:根據statistic數組,基於哈夫曼樹算法造哈夫曼樹,由於構造的過程中每次都要取最小權值的字符,所以需要用優先隊列來維護每棵樹的根節點。

③生成編碼:深度優先遍歷哈弗曼樹,得到每個葉子節點中的字符的編碼並存入字符串數組char *dictionary[MAX_CHARS];

④存儲詞頻:新建存儲壓縮數據的文件,首先寫入不同字符的個數,然后將每個字符及其對應的詞頻寫入文件。

⑤存儲壓縮數據:再次讀取待壓縮文件的每個字節byte,由dictionary[(unsigned int)byte]得到對應的編碼(注意每個字符 編碼的長度不一),使用位運算一次將編碼中的每個位(BIT)設置到一個char類       型的位緩沖中,可能多個編碼才能填滿一個位緩沖,每填滿一次,將位緩沖區以單個字節的形式寫入文件。當文件遍歷完成的時候,文件的壓縮也就完成了。

二、文件解壓:

①讀取詞頻:讀取壓縮文件,將每個字符的出現次數存入數組statistic

②構造哈夫曼編碼樹:根據statistic數組構造哈夫曼編碼樹

③繼續讀取壓縮文件,對於每個字節,使用位運算得到每個位(BIT)。對於每個BIT,根據BIT從根開始遍歷哈夫曼樹,如果BIT是0就走左分支,如果BIT是1就走有分支,走到葉子節點的時候,輸出對應的     字符。走到葉子節點后,重新從哈夫曼樹根節點開始匹配每個位。當整個壓縮文件讀取完畢時,文件解壓縮也完成了。

   

上文介紹了基於哈夫曼算法的文件壓縮和解壓縮,下面給出基於上述思想的C語言源代碼,一共有5個文件,其中pq.h和pq.c是優先隊列,compress.h和compress.c是壓縮和解壓縮的實現,main.c是測試文件。

我將整個項目文件(包括源代碼)放在了github上,點擊鏈接下載完整項目         https://github.com/C-O-L/haffuman-compress

 

下載完成之后將compress.h和pq.h添加到項目頭文件,將compress.c和pq.c和main.c添加到項目源文件,將compress.txt添加到資源文件,如下圖所示。

 其中資源文件中的compress.txt可自由編輯。

 運行main.c之后會在項目第一級目錄下產生compressed.txt文件和decompressed.txt文件

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM