哈夫曼编码和译码的实现
#include
#include
#include
#include
using namespace std;
typedef struct HuffmanTree{
int weight;
int parent,lchild,rchild;
}HTNode,*HTree;
typedef char** HuffmanCode;
const int LeafNum=8;
void HuffmanCoding(HTree& HT,int *w,int n);
void select(HTree HT,int t,int&s1,int&s2);
void HuffmanCoded(HTree& HT,HuffmanCode& HC,int n,char* p);
void translate(HTree& HT,int a,int* b,int BiLen,char* p);
void HuffmanCoding(HTree& HT,int *w,int n)
{
int s1,s2;
int m;
int i=0;
if(n<=1) return;
m=2*n-1;
HT=(HTNode*)malloc(sizeof(HTNode)*(m));
HTree p=HT;
for(i=0;i<n;++i,++p,++w)
{
*(p)={*w,-1,-1,-1};
}
for(;i<m;++i,++p)
{
*(p)={-1,-1,-1,-1};
}
cout<<"初始化后:"<<endl;
cout<<"双亲"<<'\t'<<"左孩子"<<'\t'<<"右孩子"<<'\t'<<"权值"<<endl;
for(int i=0;i<m;i++)
{
cout<<HT[i].parent<<'\t'<<HT[i].lchild<<'\t'<<HT[i].rchild<<'\t'<<HT[i].weight<<endl;
}
for(i=n;i<m;++i)
{
select(HT,i,s1,s2);
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].lchild=s1;
HT[i].rchild=s2;
HT[i].weight=HT[s1].weight+HT[s2].weight;
}
cout<<'\n'<<"完成后:"<<endl;
cout<<"双亲"<<'\t'<<"左孩子"<<'\t'<<"右孩子"<<'\t'<<"权值"<<endl;
for(int i=0;i<m;i++)
{
cout<<HT[i].parent<<'\t'<<HT[i].lchild<<'\t'<<HT[i].rchild<<'\t'<<HT[i].weight<<endl;
}
cout<<endl;
}
void HuffmanCoded(HTree& HT,HuffmanCode& HC,int n,char* p)
{
int c,start,f;
char* cd;
HC=(HuffmanCode)malloc(sizeof(char*)*(n));
cd=(char*)malloc((n)*sizeof(char));
cd[n-1]='\0';
for(int i=0;i<n;++i)
{
start=n-1;
for(c=i,f=HT[i].parent;f!=-1;c=f,f=HT[f].parent)
{
if(HT[f].lchild==c) cd[--start]='0';
else cd[--start]='1';
}
HC[i]=(char*)malloc(sizeof(char));
strcpy(HC[i],&cd[start]);
}
cout<<"哈夫曼编码为:"<<endl;
for(int i=0;i<8;i++)
{
cout<<p[i]<<'\t';
}
cout<<endl;
for(int i=0;i<n;i++)
{
cout<<HC[i]<<'\t';
}
cout<<endl;
}
void translate(HTree& HT,int a,int* b,int BiLen,char* p)
{
int n=2*a-2;
int i=0;
cout<<'\n'<<"传递的二进制消息为:"<<endl;
for(int i=0;i<BiLen;i++)
{
cout<<b[i];
}
cout<<'\n';
cout<<'\n'<<"对二进制编码译码后,其内容为:"<<endl;
for(;;)
{
if(b[i]==0&&HT[n].lchild!=-1)
{
n=HT[n].lchild;
i++;
}
else if(b[i]==1&&HT[n].rchild!=-1)
{
n=HT[n].rchild;
i++;
}
else
{
cout<<p[n];
n=2*a-2;
if(i>BiLen-1)
{
break;
}
}
}
}
void select(HTree HT,int t,int&s1,int&s2)
{
int i,m,n;
m=n=10000;
for(i=0;i<t;i++)
{
if(HT[i].parent==-1&&(HT[i].weight<m||HT[i].weight<n))
{
if(m<n)
{
n=HT[i].weight;
s2=i;
}
else
{
m=HT[i].weight;
s1=i;
}
}
}
if(s1>s2)
{
i=s1;
s1=s2;
s2=i;
}
}
int main()
{
int w[LeafNum]={5,29,7,8,14,23,3,11};
char p[LeafNum]={'h','e','c','d','l','b','o','h'};
int BiMessage[]={0,1,1,0,1,0,1,1,0,1,1,0,0,1,1,1};
int BiLen=sizeof(BiMessage)/sizeof(int);
HTree HT;
HuffmanCode HC;
HuffmanCoding(HT,w,LeafNum);
HuffmanCoded(HT,HC,LeafNum,p);
translate(HT,LeafNum,BiMessage,BiLen,p);
return 0;
}
运行结果: