Huffman檔案壓縮小專案
阿新 • • 發佈:2019-01-05
一、基礎知識鋪墊:
本質:
1、Hffman樹:
Huffman樹,又稱為最優二叉樹,是加權路徑長度最短的二叉樹。
2、採用演算法:
貪心演算法
應用:
3、分類:
4、本文主要實現一下無失真壓縮:
無損?壓縮?(思考清楚)
Huffman壓縮:出現次數差異越大越容易壓縮
5、
三叉鏈:
void GenerateHuffmanCode(Node* root)
{
//左值引用
if (root == NULL)
return;
if ((root->_left==NULL )&&( root->_right==NULL))
{
string& code = _hashInfos[root->_w._ch]._code;
Node* cur = root;
Node* parent = cur->_parent;
while (parent)
{
if (cur == parent->_left)
code += '0' ;
else
code += '1';
cur = parent;
parent = parent->_parent;
}
reverse(code.begin(), code.end());
}
GenerateHuffmanCode(root->_left);
GenerateHuffmanCode(root->_right);
}
二叉樹:
void GenerateHuffmanCode(Node* root)
{
if (root == NULL)
return;
if(root->_left==NULL&&root->_right==NULL)
_hashInfos[root->_w._ch]._code=root->_w._code;
return;
if (root->_left)
(root->_left)->_w._code = root->_w._code + "0";
GenerateHuffmanCode(root->_left);
if (root->_right)
root->_left->_w._code = root->_w._code + "1";
GenerateHuffmanCode(root->_right);
}
6、壓縮
string compressfile = file;
compressfile = file;
compressfile += ".huffman";
ofstream ofs(compressfile.c_str());
char value = 0;
int pos = 0;
ifs.clear();
ifs.seekg(0);
while (ifs.get(ch))
{
string& code = _hashInfos[ch]._code;
for (size_t i = 0; i < code.size(); ++i)
{
if (code[i] == '0')
value &= (~(1 << pos));
else if (code[i] == '1')
value |= (1 << pos);
else
assert(false);
++pos;
if (pos==8)
{
ofs.put(value);
printf("%x", value);
pos = 0;
value = 0;
}
}
}
if (pos>0)
{
ofs.put(value);
}
}
7、解壓縮
1>讀取配置檔案,重新構建Huffman樹
2>讀取壓縮檔案
由壓縮時的原理可知,此時讀到1指標向右移動,0向左移,到葉子節點停下,將字元還原。不停的迴圈,直到檔案結束或者總字元數變為0.這裡就能體現出,Huffman壓縮是一種無損的壓縮,如果程式碼沒有問題,它會原原本本的還原原始檔。
解壓到這裡成功。可以先使用小檔案測試,若沒有問題則找個大點的檔案,還有各類格式的檔案都拿來壓一壓測一下。