哈夫曼树及哈夫曼编码
题目:构建哈夫曼树的顺序存储结构,实现哈夫曼树的创建、生成叶子结点的哈夫曼编码。
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 20
#define M 2*N-1
typedef char* HuffmanCode[N+1];
typedef struct{
int weight;
int parent;
int Lchild;
int Rchild;
}HTNode,HuffmanTree[M+1];
//选两个parent为0且权值最小的结点,其序号赋给s1,s2
void select(HuffmanTree HT,int I,int *S1,int *S2){
int i,j,tmp,length=0,small_1,small_2;
int a[N+1];
for(i=1;i<=I;i++) //取出parent为零的结点的权值放到数组里
if(HT[i].parent==0){
a[length+1]=HT[i].weight;
length++; //记录数组的长度
}
for(i=1;i<length;i++) //对以上的数组排序
for(j=1;j<length-i+1;j++)
if(a[j]>a[j+1]){
tmp=a[j];
a[j]=a[j+1];
a[j+1]=tmp;
}
for(i=1;i<=I;i++) //找出最小数的数组下标
if(HT[i].weight==a[1])
small_1=i;
for(i=1;i<=I;i++)
if(HT[i].weight==a[2]&&i!=small_1)
small_2=i;
*S1=small_1;*S2=small_2;
}
//创建哈夫曼树
void CrtHuffmanTree(HuffmanTree ht,int *w,int n){
int i,m,s1,s2;
for(i=1;i<=n;i++){
ht[i].weight=w[i];
ht[i].parent=ht[i].Lchild=ht[i].Rchild=0;
}
m=2*n-1;
for(i=n+1;i<=m;i++)
ht[i].weight=ht[i].parent=ht[i].Lchild=ht[i].Rchild=0; //初始化
for(i=n+1;i<=m;i++){
select(ht,i-1,&s1,&s2);
ht[i].Lchild=s1;ht[i].Rchild=s2;
ht[i].weight=ht[s1].weight+ht[s2].weight;
ht[s1].parent=i;ht[s2].parent=i;
}
}
//哈夫曼编码
void CrtHuffmanCode(HuffmanTree ht,HuffmanCode hc,int n){
char *cd;
int i,start,c,p;
cd=(char*)malloc(n*sizeof(char));
cd[n-1]='\0';
for(i=1;i<=n;i++){
start=n-1;
c=i;
p=ht[i].parent;
while(p!=0){
start--;
if(ht[p].Lchild==c)
cd[start]='0';
else
cd[start]='1';
c=p;p=ht[p].parent;
}
hc[i]=(char*)malloc((n-start)*sizeof(char));
strcpy(hc[i],&cd[start]);
}
free(cd);
}
//输出哈夫曼树
void Output(HuffmanTree ht,int n){
int i;
printf("\n输出哈夫曼树: \n");
printf("Weight Parent Lchild Rchild \n");
for(i=1;i<=n;i++)
printf(" %d %d %d %d\n",ht[i].weight,ht[i].parent,ht[i].Lchild,ht[i].Rchild);
}
int main(){
int i,n,a,W[N+1];
HuffmanTree HT;
HuffmanCode HC;
printf("有几个叶子结点?");
scanf("%d",&n);
printf("请输入叶子结点:");
for(i=1;i<=n;i++){
scanf("%d",&a);
W[i]=a;
}
CrtHuffmanTree(HT,W,n); //创建哈夫曼树
Output(HT,n);
CrtHuffmanCode(HT,HC,n); //哈夫曼编码
printf("\n分别输出叶子结点的编码:\n");
for(i=1;i<=n;i++){
printf("%d: %s \n",HT[i].weight,HC[i]);
}
return 0;
}