利用huffman樹實現檔案壓縮
使用的編輯語言是c++,專案目的是能夠實現對檔案的壓縮及解壓,涉及到的技術主要有huffman樹的實現,檔案的io操作,優先順序佇列等;
整體思路
整個過程是依賴於huffman樹,因此要構建出乙個可供我們使用的huffman樹
壓縮時,操作原始檔,以字元形式讀取檔案資訊,進行字元個數統計,將統計結果作為資料構建huffman樹,生成huffman編碼,進行壓縮。
解壓時,從壓縮檔案取出構建huffman樹的資料,根據huffman樹解析壓縮檔案。
將資料依次放入優先順序佇列中,構建成乙個小堆。
每次從堆中拿出兩個權值最小的數,進行操作,將操作後的權值再次放入堆中。
直到堆中的資料為空,就完成了huffman數的構造。
主要實現:
//構建huffman樹需要三個引數,分別為:統計之後的資料陣列,資料個數,非空元素
huffmantree(t* data, size_t size, const t& end)
//2. 開始構建huffmantree,每堆中取兩個最小的資料,作為根節點的左子樹和右子樹,
// 並將根節點錄入堆中,直到堆中沒資料
node* pn1;
node* pn2;
node* newnode=null;
while (heap.size() > 1)
else
heap.push(newnode);
}_root = newnode;
}
檔案壓縮,首先統計原始檔的所有字元,當完成字元統計之後,將資料傳給huffman數的建構函式構造huffman樹,之後便可以根據數進行生成huffman編碼,將統計資料也要壓入壓縮檔案,方便在進行解壓之時,能夠構造出同一棵huffman樹。
在進行壓縮時,從原始檔讀取乙個字元,得到將字元的huffman編碼,將編碼以位元位的形式寫入壓縮檔案,即夠八位,進行一次寫入。
主要實現:
//從壓縮檔案中讀取乙個字元,開始從huffmantree上開始查詢,直到葉子結點,寫入解壓檔案
int ch = 0;
int num = _root->_data._count;
node* cur = _root;
while ( num > 0)
}}
解壓時,向從壓縮檔案中讀取統計資料,即:
//1.先從壓縮檔案中將要構成huffmantree的資料(字元和字元總數)取出
struct
data data;
file* fp_r = fopen(file, "rb");
fread(&data, sizeof(data), 1, fp_r);
int num = 0;
while (data._count != 0)
之後,讀取編碼,開始從huffman樹上解碼,解碼的過程是,從樹的root開始,遇到1即走樹的左子樹,遇到0走樹的右子樹,直到走到葉子結點為止,將葉子結點上的字元,輸入解壓檔案即可。
主要實現:
int ch = 0;
int num = _root->_data._count;
node* cur = _root;
while ( num > 0)
}}
經過多次的測試,雖然能夠保證無失真壓縮,但是還是存在兩個缺點:
壓縮率不能保證,有些檔案壓縮之後比壓縮之前的檔案下不了多少。
速度慢,僅僅是4m左右的檔案,也會耗費幾秒,演算法的處理還是不夠。
如果大家有什麼好的想法,可以想我提出。
專案原始碼位址:
利用huffman樹實現字元文件的壓縮
huffman樹壓縮字元文件,就是將8bit的字元根據出現頻率進行重新編碼,使編碼之後每個字元的編碼在檔案讀入時都能被唯一確定。故字元的編碼必須是不頭包含的。huffman樹是一種簡單的壓縮編碼方式。本文將採用c語言實現。編譯環境為gcc4.9.2,故可以採用c 的引用傳遞使 更加簡單。首先,先編乙...
Huffman樹的實現
huffmantree.h inte ce for the huffmantree class.if defined afx huffmantree h e2fe6c12 c0a9 4483 af1b 9623f1fd0ef8 included define afx huffmantree h e2...
Huffman實現檔案壓縮
pragma once includeusing namespace std include huffmantree.hpp typedef long long longtype define debug 檔案資訊 struct fileinfo bool operator const filein...