题目描述:
哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。
输入:
输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。
输出:
输出权值。
样例输入:
5
1 2 2 5 9
样例输出:
37
#include<stdio.h>
#include<stdlib.h>
/*哈夫曼结点数据结构*/
typedef struct Node{
int weight;
int Lch,Rch,Parent;
}HTNode,*HuffmanTree;
Select(HuffmanTree H,int N,int *p1,int *p2)
{
int i,i_;
int P[2*N-1];//创建一个新的数组用来找出H中最小的两个权重值
/*将H中的权重值全部赋给P*/
for(i = 1;i <= 2*N-1;i++){
P[i-1] = H[i].weight;
}
int t;//定义一个最小值用于冒泡排序法
for(i = 0;i < 2*N-1;i++){
for(int i_ = i+1;i_ < 2*N-1;i_++){
if(P[i] == 0&&P[i_] != 0){
t = P[i];
P[i] = P[i_];
P[i_] = t;
}else if(P[i] >= P[i_]&&P[i_] != 0){
t = P[i];
P[i] = P[i_];
P[i_] = t;
}
}
}
for(i = 1;i < 2*N-1;i++){
if(H[i].weight == P[0])
break;
}
*p2 = i;
for(i_ = 1;i_ < 2*N-1;i_++){
if(H[i_].weight == P[1]&&i_ != i)
break;
}
*p1 = i_;
}
int main()
{
int N;//叶结点数目
scanf("%d",&N);
int i,p1,p2;
/*申请一个大小为2*N的结构体数组空间(且闲置第一块数组空间)*/
HuffmanTree H;
H = (HTNode*)malloc(sizeof(HTNode)*2*N);
H[0].Lch = H[0].Parent = H[0].Rch = H[0].weight = 0;
/*对前N个叶子结点进行权重赋值且后N-1个结点全部置零*/
for(i = 1;i <= 2*N-1;i++){
if(i <= N){
H[i].Lch = H[i].Parent = H[i].Rch = 0;
scanf("%d",&H[i].weight);
}else{
H[i].Lch = H[i].Parent = H[i].Rch = H[i].weight = 0;
}
}
/*开始制哈夫曼表*/
HTNode T[2*N];
for(int i_ = 1;i_ <= 2*N-1;i_++){
T[i_].weight = H[i_].weight;
T[i_].Lch = H[i_].Lch;
T[i_].Rch = H[i_].Rch;
T[i_].Parent = H[i_].Parent;
};//T用来储存哈夫曼表
for(int i_ = 1;i_ <= N-1;i_++){
Select(H,N,&p1,&p2);
/*改变双亲和左右孩子的值,制表*/
T[N+i_].weight = H[p1].weight+H[p2].weight;
if(H[p1].weight == H[p2].weight){
T[N+i_].Lch = p1;T[N+i_].Rch = p2;T[p1].Parent = T[p2].Parent = N+i_;
}else{
T[N+i_].Lch = p2;T[N+i_].Rch = p1;T[p1].Parent = T[p2].Parent = N+i_;
}
H[p1].weight = H[p2].weight = 0;H[N+i_].weight = T[N+i_].weight;
}
/*现在所得的T即为哈夫曼表*/
for(int i_ = 1;i_ <= 2*N-1;i_++){
printf("weight[%d]=%d\t",i_,T[i_].weight);
printf("Parent[%d]=%d\t",i_,T[i_].Parent);
printf("Lch[%d]=%d\t",i_,T[i_].Lch);
printf("Rch[%d]=%d\n",i_,T[i_].Rch);
}
//此时得到的T结构体数组即为哈夫曼表
/*重新排列哈夫曼表的顺序*/
for(i = 1;i <= 2*N-1;i++){
for(int i_ = i;i_ <= 2*N-1;i_++){
if(T[i].weight < T[i_].weight){
HTNode P = T[i];
T[i] = T[i_];
T[i_] = P;
}
}
}
int Sum = 0;
for(i = 1;i <= 2*N-1;i++){
if(T[i].Lch == 0){
Sum += (T[i].weight)*(i/2);
}
}
printf("\n");
printf("Sum = %d",Sum);
}