哈夫曼编码原理请自行百度,仅贴上本咸鱼的代码与运行截图
//By Sean Chen
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <map>
#include <string>
#include <cstdlib>
using namespace std;
class treenode{
public:
char data;
int num;
treenode *leftson,*rightson;
treenode()
{
leftson=NULL;
rightson=NULL;
}
};
struct cmp{
bool operator () (treenode *a,treenode *b)
{
return a->num>b->num;
}
};
treenode *root;
map <char,string> Map; //用map存储字符对应的编码
char temp[500]; //用于存储目前遍历树时的编码
char code[10005];
char ans[100005];
priority_queue <treenode*,vector<treenode*>,cmp> Q; //优先队列,建树时有用
//建立霍夫曼树
void Buildtree()
{
int n;
printf("Input the total number of the characters:\n>");
scanf("%d",&n);
for (int i=1;i<=n;i++) //读入节点
{
treenode *tempnode=new treenode;
getchar();
printf("Input the %dth character and its frequency:\n>",i);
scanf("%c%d",&tempnode->data,&tempnode->num);
Q.push(tempnode);
}
while (Q.size()>1) //利用优先队列建树
{
treenode *a,*b,*c=new treenode;
a=Q.top(); //取优先队列头两个元素
Q.pop();
b=Q.top();
Q.pop();
/*cout<<a->data<<endl<<b->data<<endl;
system("pause");*/
c->leftson=a; //建立新节点
c->rightson=b;
c->num=a->num+b->num;
c->data='\0';
Q.push(c); //结点的权为左右子节点权值之和,并压入优先队列
}
root=Q.top();
Q.pop();
return;
}
void dfs(treenode *pos) //深搜进行编码
{
if (pos->data!='\0') //找到叶子结点
{
Map[pos->data]=temp; //编码
return;
}
if (pos->leftson!=NULL) //左子树
{
temp[strlen(temp)]='0';
dfs(pos->leftson);
temp[strlen(temp)-1]='\0';
}
if (pos->rightson!=NULL) //右子树
{
temp[strlen(temp)]='1';
dfs(pos->rightson);
temp[strlen(temp)-1]='\0';
}
return;
}
//编码
void Encode() //对字符进行编码并输出
{
memset(temp,'\0',sizeof(temp));
dfs(root);
map<char,string>::iterator iter;
for (iter=Map.begin();iter!=Map.end();iter++)
{
printf("The code of %c is: ",iter->first);
cout<<iter->second<<endl;
}
return;
}
//输出某一字符串的霍夫曼编码
void ShowCode()
{
gets(code);
printf("The Huffman-Code of %s is:\n",code);
for (int i=0;i<strlen(code);i++) //逐个字符输出
cout<<Map[code[i]];
cout<<endl;
return;
}
//将某个霍夫曼编码转为字符串,若霍夫曼编码有问题,则报错
void Decode()
{
treenode *temppos=root;
gets(code);
printf("The String of Huffman-Code %s is:\n",code);
for (int i=0;i<strlen(code);i++)
{
if (code[i]=='0' && temppos->leftson!=NULL) //编码值为‘0’,左子树
temppos=temppos->leftson;
else if (code[i]=='1' && temppos->rightson!=NULL) //右子树
temppos=temppos->rightson;
else //报错
{
printf("The Huffman-Code is Wrong!\n");
break;
}
if (temppos->data!='\0') //找到一个节点
{
printf("%c",temppos->data);
temppos=root;
}
}
cout<<endl;
return;
}
int main()
{
Buildtree();
int flag=1;
int oper;
while (flag)
{
system("cls");
memset(ans,'\0',sizeof(ans));
memset(code,'\0',sizeof(code));
Encode();
printf("choose your operation:\n1:Encode a String\n2:Decode a String\n3:End\n>");
scanf("%d",&oper);
getchar();
switch (oper)
{
case 1:
{
ShowCode();
system("pause");
break;
}
case 2:
{
Decode();
system("pause");
break;
}
case 3:
{
flag=0;
break;
}
default:
{
printf("Wrong Input,Please Input again!");
system("pause");
break;
}
}
}
return 0;
}
附上两张运行截图,分别为编码和解码