通信的电文由字符集中的字母构成,每个字母在电文中会有一个出现的频率。为这些字母设计相应的哈夫曼编码!方法:每次在哈夫曼树构造过程中,两个最小数的选择总是最小的在左,而次小的在右。
输入输出样例:1组
#1
- 样例输入:
abcdefg# //#代表结束符 0.31 0.16 0.10 0.08 0.11 0.20 0.04 //代表每个字母的出现频率
- 样例输出:
a:11 b:101 c:010 d:1001 e:011 f:00 g:1000
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 100
typedef struct
{
float weight;
char lchild;
char rchild;
int parent;
} HType;
typedef struct
{
char ch;
int hfm[max];
int start;
} HCode;
void Creat_huffMTree(HType HFMTree[],int n)
{
int y1,y2,x1,x2;
int i,j;
HCode hc;
for(i=0; i<2*n-1; i++) //HFMTree初始化
{
HFMTree[i].weight=0;
HFMTree[i].parent=-1;
HFMTree[i].lchild=-1;
HFMTree[i].rchild=-1;
}
for(i=0; i<n; i++) //输入n个叶子节点的权值
{
scanf("%f",&HFMTree[i].weight);
}
for(i=0; i<n-1; i++)
{
x1=x2=max;
y1=y2=0;
for(j=0; j<n+i; j++) //找出根最小和次小权值的两棵树
{
if(HFMTree[j].parent==-1&&HFMTree[j].weight<x1)
{
x2=x1;
y2=y1;
x1=HFMTree[j].weight;
y1=j;
}
else if(HFMTree[j].parent==-1&&HFMTree[j].weight<x2)
{
x2=HFMTree[j].weight;
y2=j;
}
}
HFMTree[y1].parent=n+i;
HFMTree[y2].parent=n+i;//将找出的两棵树合并成一棵树
HFMTree[n+i].weight=HFMTree[y1].weight+HFMTree[y2].weight;
HFMTree[n+i].lchild=y1;
HFMTree[n+i].lchild=y2;
}
}
void createHFMCode(HType HFMTree[], HCode HFMCode[], int n)
{
HCode hc;
int i, j, r, p;
for(i = 0; i < n; i++)
{
hc.start = max - 1;
r = i;
p = HFMTree[r].parent;
while(p != -1)
{
if(HFMTree[p].lchild == r)
hc.hfm[hc.start] = 0;
else
hc.hfm[hc.start] = 1;
hc.start--;
r = p;
p = HFMTree[r].parent;
}
for(j = hc.start + 1; j < max; j++)
HFMCode[i].hfm[j] = hc.hfm[j];
HFMCode[i].start = hc.start + 1;
}
}
int main()
{
char arr[max];
int n,i=0,j;
HCode hcode[max];
while(arr[i]!='#')
{
scanf("%c",&arr[i]);
hcode[i].ch=arr[i];
i++;
}
n = i;
HType HFMTree[2*n-1];
Creat_huffMTree(HFMTree,n);
createHFMCode(HFMTree,hcode,n);
for(i=0; i<n; i++)
{
printf("%c:",hcode[i].ch);
for(j= hcode[i].start;j<max;j++)
printf("%d",hcode[i].hfm[j]);
printf("\n");
}
return 0;
}