Huffman编码
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
哈弗曼编码大家一定很熟悉吧(不熟悉也没关系,自己查去。。。)。现在给你一串字符以及它们所对应的权值,让你构造哈弗曼树,从而确定每个字符的哈弗曼编码。当然,这里有一些小规定:
1.规定哈弗曼树的左子树编码为0,右子树编码为1;
2.若两个字符权值相同,则ASCII码值小的字符为左孩子,大的为右孩子;
3.创建的新节点所代表的字符与它的左孩子的字符相同;
4.所有字符为ASCII码表上32-96之间的字符(即“ ”到“`”之间的字符)。
-
输入
-
输入包含多组数据(不超过100组)
每组数据第一行一个整数n,表示字符个数。接下来n行,每行有一个字符ch和一个整数weight,表示字符ch所对应的权值,中间用空格隔开。
输入数据保证每组测试数据的字符不会重复。
输出
- 对于每组测试数据,按照输入顺序输出相应的字符以及它们的哈弗曼编码结果,具体格式见样例。 样例输入
-
3 a 10 b 5 c 8 4 a 1 b 1 c 1 d 1
样例输出
-
a:0 b:10 c:11 a:00 b:01 c:10 d:11
-
代码:
-
#include<stdio.h> #include<string.h> #include<stdlib.h> #define INF 99999999 struct node { char ch; char *str; // 用于存储Huffman编码 int weight; int parent; int LChild; int RChild; }num[200]; int main() { int n,min1,min2,s1,s2,i,j,m; int start,c,p; char *cd; // 临时存储Huffman编码 while(~scanf("%d",&n)) { for(i=1;i<=n;i++) { getchar(); scanf("%c%d",&num[i].ch,&num[i].weight); num[i].parent=0; num[i].LChild=0; num[i].RChild=0; } m=2*n; for(i=n+1;i<m;i++) { num[i].weight=0; num[i].parent=0; num[i].LChild=0; num[i].RChild=0; } // 构造Huffman树 for(i=n+1;i<m;i++) { min1=min2=INF; s1=s2=0; for(j=1;j<=i-1;j++) { if(num[j].parent!=0) continue; if(min1>num[j].weight) { min2=min1; min1=num[j].weight; s2=s1; s1=j; } else if(min1==num[j].weight&&num[s1].ch>num[j].ch) { min2=min1; min1=num[j].weight; s2=s1; s1=j; } else if(min2>num[j].weight) { min2=num[j].weight; s2=j; } else if(min2==num[j].weight&&num[s2].ch>num[j].ch) { min2=num[j].weight; s2=j; } } num[i].weight=num[s1].weight+num[s2].weight; num[s1].parent=i; num[s2].parent=i; if(num[s1].weight==num[s2].weight) { if(num[s1].ch>num[s2].ch) { num[i].ch=num[s2].ch; num[i].LChild=s2; num[i].RChild=s1; } if(num[s1].ch<num[s2].ch) { num[i].ch=num[s1].ch; num[i].LChild=s1; num[i].RChild=s2; } } else { num[i].ch=num[s1].ch; num[i].LChild=s1; num[i].RChild=s2; } } // Huffman树构造完毕 // 求Huffman编码 cd=(char *)malloc(n*sizeof(char)); cd[n-1]='\0'; for(i=1;i<=n;i++) { start=n-1; c=i; p=num[i].parent; while(p!=0) { --start; if(num[p].LChild==c) cd[start]='0'; else cd[start]='1'; c=p; p=num[p].parent; } num[i].str=(char *)malloc((n-start)*sizeof(char)); strcpy(num[i].str,&cd[start]); } free(cd); for(i=1;i<=n;i++) printf("%c:%s\n",num[i].ch,num[i].str); } return 0; }
-
输入包含多组数据(不超过100组)