Huffman编码是通信系统中常用的一种不等长编码,它的特点是:能够使编码之后的电文长度最短。
输入:
第一行为要编码的符号数量n
第二行~第n+1行为每个符号出现的频率
输出:
对应哈夫曼树的带权路径长度WPL
测试输入 | 期待的输出 | 时间限制 | 内存限制 | 额外进程 | |
---|---|---|---|---|---|
测试用例 1 | 以文本方式显示
|
以文本方式显示
|
1秒 | 64M | 0 |
测试用例 2 | 以文本方式显示
|
以文本方式显示
|
1秒 | 64M | 0 |
#include
#include
typedef struct{
int weight;
int parent,lchild,rchild,depth;
}HTNode,*HuffmanCode;
void select(HuffmanCode &HT,int num,int &s1,int &s2)
{
int a[num+1],temp,i,j;
for(i=1;i<=num;i++) a[i]=i;
for(i=1;i<=num-1;i++)
{
for(j=1;j<=num-1;++j)
{
if(HT[a[j]].weight>HT[a[j+1]].weight)
{
temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
}
}
}
for(i=1;i<=num;++i)
{
if(HT[a[i]].parent==0)
{
s1=a[i];
break;
}
}
for(i++;i<=num;++i)
{
if(HT[a[i]].parent==0)
{
s2=a[i];
break;
}
}
return;
}
void dep(HuffmanCode &HT,int i) //改变叶子结点深度
{
if(HT[i].lchild!=0)
{
HT[HT[i].lchild].depth++;
dep(HT,HT[i].lchild);
}
if(HT[i].rchild!=0)
{
HT[HT[i].rchild].depth++;
dep(HT,HT[i].rchild);
}
return;
}
int main()
{
int n,m,wpl=0;
scanf("%d",&n);
getchar();
m=2*n-1;
HuffmanCode HT;
HT=(HuffmanCode)malloc((m+1)*sizeof(HTNode)); //结构数组,从1开始,HT为数组指针
HuffmanCode p;
int i,w,s1,s2;
for(p=HT+1,i=1;i<=n;++i,++p)
{
scanf("%d",&w);
getchar();
*p={w,0,0,0,0};
}
for(;i<=m;++i,++p) *p={0,0,0,0,0};
for(i=n+1;i<=m;++i) //建立赫夫曼树
{
select(HT,i-1,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;
dep(HT,i);
}
for(i=1;i<=n;++i)
{
wpl+=HT[i].depth*HT[i].weight;
//printf("%d,%d\n",HT[i].depth,HT[i].weight);
}
printf("WPL=%d\n",wpl);
return 0;
}