#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;
}
结果截图: