一、基础知识铺垫:
本质:
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压缩是一种无损的压缩,如果代码没有问题,它会原原本本的还原源文件。
解压到这里成功。可以先使用小文件测试,若没有问题则找个大点的文件,还有各类格式的文件都拿来压一压测一下。