一、 实验题目:
树的应用——哈夫曼编码
二、 实验内容:
利用哈夫曼编码进行通信可以大大提高信道的利用率,缩短信息传输的时间,降低传输成本。根据哈夫曼编码的原理,编写一个程序,在用户输入结点权值的基础上求哈夫曼编码。
从键盘输入若干字符及每个字符出现的频率,将字符出现的频率作为结点的权值,建立哈夫曼树,求出各字符的哈夫曼编码。要求:
1. 输出存放哈夫曼树的数组HT的初态和终态;
2. 输出每个字符的哈夫曼编码;
3. 输入由上述若干字符组成的字符串,对电文进行编码并输出;
4. (选做)输入电文的哈夫曼编码,进行译码并输出。
三、 实验要求:
1. 使用C语言完成算法设计和程序设计并上机调试通过。
2. 撰写实验报告,提供实验结果和数据。
3. 写出算法设计小结和心得。
四、 程序源代码:
#include<stdio.h>
#include<stdlib.h>
#define M 10
typedef struct{
char data;
int weight,parent,lchild,rchild;
}HTNode,*HuffmanTree;
typedef struct{
char cd[M];
int start;
}huffnode;
typedef char * *HuffmanCode;
void Coding(HuffmanTree &HT,huffnode hcd[],int n,char str[]) {
for (int i=0;str[i]!='\0';i++) {
for (int j=1;j<=n;j++) {
if (str[i]==HT[j].data) {
for (int k=hcd[j].start;k<=n;k++) {
printf("%c",hcd[j].cd[k]);
}
break;
}
}
}
printf("\n");
}
void HuffmanCoding(HuffmanTree &HT,int n){
int m,i,s1,s2,m1,m2,k;
int c,f;
huffnode hcd[20],d;
m=2*n-1;
HuffmanTree p;
p=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));
if(n<1) return;
for( i=1;i<=2*n-1;++i){
HT[i].data=HT[i].parent=HT[i].lchild=HT[i].rchild=HT[i].weight=0;
}
for(p=HT,i=1;i<=n;++i) {
getchar();
printf("第%d个元素的\n结点值",i);
scanf("%c",&HT[i].data);
printf("\t权重: ");
scanf("%d",&HT[i].weight);
p[i].data=HT[i].data;
p[i].weight=HT[i].weight;
}
printf("哈夫曼树初始\n");
printf("\tdata\tweight\tparent\tlchild\trchild\n");
for( i=1;i<=2*n-1;++i){
printf("\t%c\t%d\t%d\t%d\t%d\n",HT[i].data,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
for(i=n+1;i<=m;i++){
m1=m2=32767;
s1=s2=0;
for (int k=1; k<=i-1; k++)
{ if ((HT[k].parent==0)&&(HT[k].weight<m1))
{ m2=m1; s2=s1;
m1=HT[k].weight;
s1=k;
}
else if ((HT[k].parent==0)&&(HT[k].weight<m2))
{ m2=HT[k].weight;
s2=k;
}
}
HT[s1].parent=i;
HT[s2].parent=i;
HT[i].weight=HT[s1].weight+HT[s2].weight;
HT[i].lchild=s1;
HT[i].rchild=s2;
}
printf("哈夫曼树终态\n");
printf("\tdata\tweight\tparent\tlchild\trchild\n");
for( i=1;i<=2*n-1;++i){
printf("\t%c\t%d\t%d\t%d\t%d\n",HT[i].data,HT[i].weight,HT[i].parent,HT[i].lchild,HT[i].rchild);
}
//哈弗曼的编码
for (i=1;i<=n;i++) {
d.start=n+1;
c=i;
f=HT[i].parent;
while(f){
if(HT[f].lchild==c)
d.cd[--d.start]='0';
else
d.cd[--d.start]='1';
c=f;
f=HT[f].parent;
}
hcd[i]=d;
}
printf("哈夫曼编码:\n");
printf("结点信息\t权值\t哈夫曼编码\n");
for (i=1;i<=n;i++) {
printf("%c\t\t%d\t",HT[i].data,HT[i].weight);
for ( k=hcd[i].start;k<=n;k++)
printf("%c",hcd[i].cd[k]);
printf("\n");
}
char str[20];
printf("请输入译文:\n");
scanf("%s",str);
printf("译码后为:");
Coding(HT, hcd,n,str);
}
void main(){
HuffmanTree HT;
int n,j;
printf("元素个数");scanf("%d",&n);
HuffmanCoding(HT, n);
}