基于Huffman编码的文件压缩/解压缩

基于Huffman编码的文件压缩

文件压缩(*.zip):简单来说就是让文件原本所占空间变小

主要过程和原理:


压缩步骤

  • 1、获取源文件中每个字符出现的次数
  • 2、以每个字符出现的次数为权值创建huffman树
  • 3、根据Huffman树获取每个字符的编码
  • 4、根据每个字符的编码重新改写源文件

压缩原理

  • 1 .整个压缩过程的重点都在于Huffman树上,所以主要是构建Huffman树,利用Huffman树的权值来记录文件中每个字符出现的次数
  • 2 .Huffman树:最优二叉树,Huffman树是带权路径长度最短的树,权值较大的结点离根较近,所以,用权值来记录每个树出现的次数,并且用编码记录字符所在位置
  • 3 .令每一个出现的字符都为二叉树的叶子节点(每条路径只有一个叶子节点),遍历二叉树中每个节点并且记录权值,写到压缩文件中,从而完成对文件的压缩

压缩过程
1.创建Huffman树(HuffmanFile.hpp)

  • 注:
  • 由于需要用到类模板,所以创建.hpp文件
  • 建立小堆:为了获取每个字符最小权值,利用优先级队列建立小堆
  • 字符编码:规定路径左为0,路径右为1,以便于记录压缩文件

二叉树实例:
如文件数据:aaaabbddcccccd

在这里插入图片描述
2.创建.hzp文件(CompressFile.h&CompressHuff.cpp)

二进制读取文件,统计出256个字符中各字符出现的次数以及字符出现的总次数;
调用Huffman树生成Huffman编码;
按照源文件压缩数据:每8位为一个字节写入压缩文件,当余下的不够一个字节时,在后面补0够一个字节再写入
加入配置信息:字符出现的总次数以及各个字符出现的次数


压缩原理

解压步骤

  • 1、获取.hzp压缩文件
  • 2、获取压缩文件的信息
  • 3、还原Huffman树
  • 4、解压缩

解压过程
如果掌握的压缩技巧后,解压的过程相对简单
解压文件属于将压缩文件反向来看:读取压缩文件中的配置信息和二叉树编码,利用resever将二叉树中编码逆置,还原二叉树,从而解压文件

关键代码:

//Huffman树的创建
//1.创建二叉树节点
template<class W>
struct HuffmanTreeNode{
	HuffmanTreeNode(const W& weight)
	:_pLeft(nullptr)
	, _pRight(nullptr)
	, _pParent(nullptr)
	, _weight(weight)
	{}
	HuffmanTreeNode<W>* _pLeft;
	HuffmanTreeNode<W>* _pRight;
	HuffmanTreeNode<W>* _pParent;
	W _weight;  //权值
};
//2.由于优先级队列默认是大堆,所以我们需要利用仿函数重新定义排序规则
template<class W>
struct  Compare{
	typedef HuffmanTreeNode<W>* PNode;
	bool operator()(const PNode pLeft, const PNode pRight)
	{
		return pLeft->_weight > pRight->_weight;    //仿函数构造小堆
	}
};
//3.构造一个Huffman类,对二叉树进行创建排列与销毁
class HuffmanTree{};
//
//压缩与解压中的主要函数 (CompressFile.h)
class FileCompressHuffM
{
public:
	 FileCompressHuffM();
	void CompressFile(const string& strFilePath);
	void UNCompressFile(const string& strFilePath);
	void WriteHead(FILE* fOut, const string& strFilePath); //文件头部信息
private:
	void HuffmanCode(HuffmanTreeNode<CharInfo>* proot);
	void GetLine(FILE* fIn, string& strContent); 
private:
	vector<CharInfo>_charInfo;
};

源代码地址
码云地址:https://gitee.com/CoolShaw_skr/Cpp/tree/master/文件压缩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值