题目链接:http://ac.jobdu.com/problem.php?pid=1172
-
题目描述:
-
哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
-
输入:
-
输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
-
输出:
-
输出权值。
-
样例输入:
-
5 1 2 2 5 9
-
样例输出:
-
37
AC代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct Node{
int weight;
Node *Rchild,*Lchild;
}Node,*NodeP;
int compute(Node*p,int k);
int cmp(const void*p,const void*q);
int main()
{
int n;
Node *node[2000];
Node *p;
while(scanf("%d",&n)!=EOF)
{
for(int i=0;i<n;i++)
{
node[i]=(Node*)malloc(sizeof(Node)); //申请内存空间
scanf("%d",&(node[i]->weight));
node[i]->Rchild=node[i]->Lchild= NULL;
}
for(int i=0;i<n-1;i++) //for循环构造哈夫曼树
{
qsort(&node[i],n-i,sizeof(Node *),cmp);
p=(Node*)malloc(sizeof(Node));
p->Rchild=node[i];
p->Lchild=node[i+1];
p->weight=node[i]->weight+node[i+1]->weight;
node[i+1]=p;
}
printf("%d\n",compute(p,0));
}
return 0;
}
int compute(Node*p,int k) //用递归求最短带权路径长度
{
if(p!=NULL)
{
if(p->Rchild==NULL&&p->Lchild==NULL)
{
return p->weight*k;
}
k++;
return compute(p->Rchild,k)+compute(p->Lchild,k);
}
else
{
return 0;
}
}
int cmp(const void*p,const void*q) //比较函数,根据指针所指结点权值大小进行排序
{
NodeP *a=(NodeP*)p;
NodeP *b=(NodeP*)q;
return (*a)->weight - (*b)->weight;
}