哈夫曼编码

#include<string>
#include<vector>
#include<iostream>
#include<queue>
#include<unordered_set>
#include<algorithm>
#include<cassert>
#include<list>
#include<map>
#include<fstream>
#include<memory>

using namespace std;


//编码树节点
struct Node
{
	Node *pLeft;
	Node *pRight;
	char cur;
	int  weight;
	Node():pLeft(NULL),pRight(NULL),cur(0),weight(0) {};
};

struct NodeCmp
{
	bool operator()(const Node* const a,const Node* const b)
	{
		return a->weight>b->weight?true:false;
	}
};

class Huffman
{
public:
	static bool Encode(const string &src,const string &dest)
	{
		//统计每个字符出现的次数
		map<char,int> dict;
		FILE * fSrc=fopen(src.c_str(),"r");
		char cur;
		while(fread(&cur,sizeof(char),1,fSrc) && !feof(fSrc))
		{
			dict[cur]++;
		}
		fclose(fSrc);
		//构造优先队列
		priority_queue<Node*,vector<Node*>,NodeCmp> NodeQueue;
		for(auto i=dict.begin();i!=dict.end();i++)
		{
			Node *pNode=new Node();
			//cout<<pNode<<endl;
			pNode->cur=i->first;
			pNode->weight=i->second;
			NodeQueue.push(pNode);
		}
		//根据优先队列构造编码树
		cout<<endl;
		Node *root=NULL;
		while(NodeQueue.size()>1)
		{
			Node *pLeft=NodeQueue.top();
			//cout<<pLeft<<endl;
			NodeQueue.pop();
			Node *pRight=NodeQueue.top();
			//cout<<pRight<<endl;
			NodeQueue.pop();
			root=new Node();
			root->pLeft=pLeft;
			root->pRight=pRight;
			root->weight=pLeft->weight+pRight->weight;
			//cout<<root<<endl;
			NodeQueue.push(root);
		}
		//由编码树得到编码
		ofstream outfile;
	    outfile.open(dest.c_str(),ofstream::out);
		printCode(root,"",outfile);

	}
private:
	static void printCode(Node *root,string coded,ofstream &outfile)
	{
		if(root==NULL)  return;
		if(root->pLeft==NULL && root->pRight==NULL)
		{
			outfile<<root->cur<<"    "<<coded<<endl;
			return;
		}
		if(root->pLeft)
		{
			printCode(root->pLeft,coded+"0",outfile);
		}
		if(root->pRight)
		{
			printCode(root->pRight,coded+"1",outfile);
		}
	}
};

int main ()
{
  string src("d:\\Huffman.txt");
  string dest("d:\\huffmancode.txt");
  Huffman::Encode(src,dest);
  return 0;
}

结果截图:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值