【数据结构】文件压缩项目

本文介绍了一个使用C++和面向对象编程实现的文件压缩项目,主要运用了哈夫曼树和哈夫曼编码。通过小堆建立哈弗曼树,生成哈夫曼编码对文件进行压缩,同时生成配置文件以便解码。解压过程则依赖于配置文件重建哈弗曼树,完成文件的解压缩。项目包括对不同类型文件(如普通文件、图片和视频)的压缩与解压缩效果分析,验证了压缩前后文件内容的一致性和大小变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目名称:文件压缩

开发环境:vs2010

运用到的数据结构:

1、heap堆

2、huffmantree哈夫曼树

3、Huffmancode哈夫曼编码

4、面向对象C++编程语言

思路:

1、利用小堆建立哈弗曼树

2、利用哈弗曼树产生哈夫曼编码

3、利用哈夫曼编码对文件进行压缩,产生压缩文件**.compress文件,以及**.config配置文件方便解码

4、利用配置文件获取到文件中每个字符出现的次数

5、利用配置文件用小堆再次建立哈弗曼树

6、利用配置文件建立的哈弗曼树进行解码生成解压后的文件**.uncompress

建立大小堆博文连接在下面

http://blog.youkuaiyun.com/shangguan_1234/article/details/52791719

堆结构的二叉树存储是
最大堆:每个父节点的都大于孩子节点。
最小堆:每个父节点的都小于孩子节点。

这里举小堆的例子

将每个子孩子与父节点的值进行比较,如果比父节点小则父节点下移,较小的子孩子上移


#pragma once    
#include <vector>    
#include<assert.h>    
using namespace std;
// 小堆    
template<class T>
struct Less
{
	bool operator() (const T& l, const T& r)
	{
		return l < r;
	}
};
//大堆
template<class T>
struct Greater
{
	bool operator() (const T& l, const T& r)
	{
		return l > r;
	}
};

template<class T, class Compare = Less<T>>
class Heap
{
public:
	Heap()
	{}

	Heap(const T* a, size_t size)
	{
		for (size_t i = 0; i < size; ++i)
		{
			_infosays.push_back(a[i]);
		}

		// 建堆    
		for (int i = (_infosays.size() - 2) / 2; i >= 0; --i)
		{
			AdjustDown(i);
		}
	}

	void Push(const T& x)
	{
		_infosays.push_back(x);
		AdjustUp(_infosays.size() - 1);
	}

	void Pop()
	{
		assert(_infosays.size() > 0);
		swap(_infosays[0], _infosays[_infosays.size() - 1]);
		_infosays.pop_back();

		AdjustDown(0);
	}

	const T& Top()
	{
		//assert(_infosays.size() > 0);
		if (!Empty())
		{
			return _infosays[0];
		}
		
	}

	bool Empty()
	{
		return _infosays.empty();
	}

	int Size()
	{
		return _infosays.size();
	}

	void AdjustDown(int root)
	{
		size_t child = root * 2 + 1;

		Compare com;
		while (child < _infosays.size())
		{
			if (child + 1<_infosays.size() &&
				com(_infosays[child + 1], _infosays[child]))
			{
				++child;
			}


			if (com(_infosays[child], _infosays[root]))
			{
				swap(_infosays[child], _infosays[root]);
				root = child;
				child = 2 * root + 1;
			}
			else
			{
				break;
			}
		}
	}

	void AdjustUp(int child)
	{
		int parent = (child - 1) / 2;


		while (child > 0)
		{
			if (Compare()(_infosays[child], _infosays[parent]))
			{
				swap(_infosays[parent], _infosays[child]);
				child = parent;
				parent = (child - 1) / 2;
			}
			else
			{
				break;
			}
		}
	}

	void Print()
	{
		for (size_t i = 0; i < _infosays.size(); ++i)
		{
			cout << _infosays[i] << " ";
		}
		cout << endl;
	}

public:
	vector<T> _infosays;
};

利用堆建立哈夫曼树

Huffm an树,又称为最优二叉树,是加权路径长度最短的二叉树。
【贪心算法】是指在问题求解时,总是做出当前看起来最好的选择。也就是说贪心算法做出的不是整体最优的的选择,而是某种意义上的
局部最优解。贪心算法不是对所有的问题都能得到整体最优解。

使用贪心算法构建Huffman树


#pragma  once 
#include "Heap.h"    
#include<assert.h>    
using namespace std;
template<class T>
struct HuffmanTreeNode
{
	HuffmanTreeNode<T>* _left;
	HuffmanTreeNode<T>* _right;
	HuffmanTreeNode<T>* _parent;
	T _weight;
	HuffmanTreeNode(const T& x)
		:_weight(x)
		, _left(NULL)
		, _right(NULL)
		, _parent(NULL)
	{}
};

template<class T>
class HuffmanTree
{
	typedef HuffmanTreeNode<T> Node;

public:

	HuffmanTree()
		:_root(NULL)
	{}

	~HuffmanTree()
	{
		Destory(_root);
	}

	template <class T>
	struct NodeCompare
	{
		bool operator()(Node *l, Node *r)
		{
			return l->_weight < r->_weight;
		}
	};
	void CreatTree(const T* a, size_t size, const T& invalid)
	{
		assert(a);
		Heap<Node*, NodeCompare<T>> minHeap;
		for (size_t i = 0; i < size; ++i)
		{
			if (a[i] != invalid)
			{
				Node* node = new Node(a[i]);
				minHeap.Push(node);
			}
		}

		while (minHeap.Size() > 1)
		{
			Node* left = minHeap.Top();
			minHeap.Pop();
			Node* right = minHeap.Top();
			minHeap.Pop();

			Node* parent = new Node(left->_weight + right->_weight);
			parent->_left = left;
			parent->_right = right;
			left->_parent = parent;
			right->_parent = parent;

			minHeap.Push(parent);
		}

		_root = minHeap.Top();
	}


	Node* GetRootNode()
	{
		return _root;
	}


	//void Destory(Node* root)
	//{
	//	if (root)
	//	{
	//		Destory(root->_left);
	//		Destory(root->_right);
	//		delete root;
	//		root = NULL;
	//	}
	//}
	void Destory(Node* root)
	{
		if (root==NULL)
		{
			return ;
		}
		if(root->_left==NULL&&root->_right==NULL)
		{
			delete root;
			root=NULL;
		}
		else
		{
			Destory(root->_left);
			Destory(root->_right);
		}
	}
private:
	HuffmanTreeNode<T>* _root;
};

利用哈弗曼树产生哈夫曼编码


代码实现

void _GenerateHuffmanCode(HuffmanTreeNode<CharInfo>* root)//创建哈夫曼编码
	{
		if (root == NULL
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值