标题
huffman编码
时间限制
2 S
内存限制
10000 Kb
问题描述
假设用于通信的电文由n(4<n<30)个字符组成,字符在电文中出现的频度(权值)为w1w2…wn,试根据该权值序列构造哈夫曼树,并计算该树的带权路径长度。
问题输入
一组数据,第1行为n的值,第2行为n个整数,表示字符的出现频度。
问题输出
输出一个整数,表示所构造哈夫曼树的带权路径长度。
输入样例
8
7 19 2 6 32 3 21 10
输出样例
261
#include<stdio.h>
int main()
{
int n;
scanf("%d",&n);
int a[n][n+1];
int b[n];
//输入数据
for(int i=0;i<n;i++)
{
scanf("%d",&a[i][0]);
}
//数据排序,从小到大;
for(int i=0;i<n-1;i++)
{
for(int j=i;j<n;j++)
{
if(a[i][0]<a[j][0])
{
int t=a[i][0];
a[i][0]=a[j][0];
a[j][0]=t;
}
}
}
for(int i=0;i<n;i++)
{
b[i]=a[i][0];
}
//二维数组置-1
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
a[i][j+1]=0;
}
}
//二维数组赋值
for(int i=n-1;i>=0;i--)
{
a[i][i+1]=1;
}
//测试是否重置成功
/* for(int i=0;i<n;i++)
{
for(int j=0;j<n+1;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
*/
//i次循环计算
for(int i=0;i<n-1;i++)
{
//
a[n-i-2][0]=a[n-i-1][0]+a[n-i-2][0];
for(int j=0;j<n;j++)
{
if(a[n-i-2][j+1]>0||a[n-i-1][j+1]>0)
{
a[n-i-2][j+1]=a[n-i-2][j+1]+a[n-i-1][j+1];
if(a[n-i-2][j+1]>0)
{
a[n-i-2][j+1]=a[n-i-2][j+1]+1;
}
}
}
for(int j=0;j<n-i-1;j++)
{
for(int k=j;k<n-i;k++)
{
if(a[j][0]<a[k][0])
{
int t=a[j][0];
a[j][0]=a[k][0];
a[k][0]=t;
for(int p=0;p<n;p++)
{
int e=a[j][p+1];
a[j][p+1]=a[k][p+1];
a[k][p+1]=e;
}
}
}
}
//检验是否递增正确
/* for(int u=0;u<n-i-1;u++)
{
printf("%d ",a[u][0]);
}
printf("\n");
*/
}
int sum=0;
//测试结果数组
/* for(int i=0;i<n;i++)
{
for(int j=0;j<n+1;j++)
{
printf("%d ",a[i][j]);
}
printf("\n");
}
*/
for(int i=0;i<n;i++)
{
sum=sum+(a[0][i+1]-1)*b[i];
//得出结果 printf("%d %d\n",a[0][i+1]-1,b[i]);
}
printf("%d\n",sum);
}