样例输入(自己设的测试值):
7
40 30 15 5 4 3 3
A B C D E F G
#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_;
}
Code(HuffmanTree T,int root,int N,int i)
{
int i_ = i;
if(T[T[i].Parent].weight != root){
i = T[i].Parent;
Code(T,root,N,i);
}
if(T[T[i_].Parent].Lch == i_){
printf("0");
}else{
printf("1");
}
}
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);
}
/*输出叶结点所对应的哈夫曼编码值*/
for(int i_ = 1;i_ <= N;i_++){
printf("%c = ",'A'+i_-1);
Code(T,T[2*N-1].weight,N,i_);
printf("\n");
}
}
经验证与所画树的叶结点编码值相同 ! ^ _ ^ !