根据输入的字符串,计算字符的频率,构建哈夫曼编码
#include<iostream>
#include<string>
#include<map>
using namespace std;
typedef char ** HuffmandCode;
typedef struct node{
int value;
int left,right,parent;
}HTNode,*HuffmandTree;
void select(HuffmandTree HT,int end,int *s1,int*s2)
{
int min1,min2;
int i=1;
while(HT[i].parent!=0&&i<=end)
{
i++;
}//要找到父节点为0的那些节点,她们还没构成树
min1=HT[i].value;
*s1=i;
i++;
while(HT[i].parent!=0&&i<=end)
{
i++;
}
if(HT[i].value<min1)
{
min2=min1;
*s2=*s1;
min1=HT[i].value;
*s1=i;
}
else{
min2=HT[i].value;
*s2=i;
}
for(int j=i+1;j<=end;j++)
{
if(HT[j].parent!=0)
continue;
if(HT[j].value<min1)
{
min2=min1;
*s2=*s1;
min1=HT[j].value;
*s1=j;
}
else if(HT[j].value>=min1&&HT[j].value<min2)
{
min2=HT[j].value;
*s2=j;
}
}
}
void createHuffmand(HuffmandTree *HT,int *w,int n)
{
if(n<=1)
return;//只有一个编码
int m=2*n-1;//哈夫曼树的节点数
*HT=(HuffmandTree)malloc((m+1)*sizeof(HTNode));//0号位置不用
HuffmandTree p=*HT;//初始化哈夫曼树
for(int i=1;i<=n;i++)
{
(p+i)->value=*(w+i-1);
(p+i)->parent=0;
(p+i)->left=0;
(p+i)->right=0;
}
for(i=n+1;i<=m;i++)
{
(p+i)->value=0;
(p+i)->parent=0;
(p+i)->left=0;
(p+i)->right=0;
}
///构建哈夫曼树
for(i=n+1;i<=m;i++)
{
int s1,s2;
select(*HT,i-1,&s1,&s2);
(*HT)[s1].parent=i;
(*HT)[s2].parent=i;
(*HT)[i].left=s1;
(*HT)[i].right=s2;
(*HT)[i].value=(*HT)[s1].value+(*HT)[s2].value;
}
}
void HuffmandCoding(HuffmandTree HT,HuffmandCode *HC,int n)
{
*HC=(HuffmandCode)malloc((n+1)*sizeof(char *));
char *cd=(char*)malloc(n*sizeof(char));//用于存放编码
cd[n-1]='\0';
for(int i=1;i<=n;i++)//从叶子节点出发,逆序
{
int start=n-1;//逆序存储
int c=i;
int j=HT[i].parent;
while(j!=0)
{
if(HT[j].left==c)
cd[--start]='0';
else
cd[--start]='1';
c=j;
j=HT[j].parent;
}
(*HC)[i]=(char *)malloc((n-start)*sizeof(char));
strcpy((*HC)[i],&cd[start]);
}
free(cd);
}
//void print(HuffmandCode htable,int *w,int n)
//{
// for(int i=1;i<=n;i++)
// {
// cout<<htable[i];
// }
// cout<<endl;
//}
int main(){
string str;
cin>>str;
int len=str.size();
map<char,int> arr;
for(int i=0;i<len;i++)
{
arr[str[i]]++;
}
len=arr.size();
int *w=(int*)malloc(len*sizeof(int));//存放频率的数组
i=0;
for(map<char,int>::iterator it=arr.begin();it!=arr.end();it++)
{
w[i]=it->second;
// cout<<w[i];
i++;
}
HuffmandTree htree;
HuffmandCode htable;
createHuffmand(&htree,w,len);
HuffmandCoding(htree,&htable,len);
map<char,char*> codes;
it=arr.begin();
for(i=1;i<=len;i++)
{
codes[it->first]=htable[i];
it++;
}
for(i=0;i<str.size();i++)
{
cout<<codes[str[i]];
}
cout<<endl;
return 0;
}