问题 D: Haffman编码
原创
©著作权归作者所有:来自51CTO博客作者fanxinglanyu的原创作品,请联系作者获取转载授权,否则将追究法律责任
1 题目
问题 D: Haffman编码
[命题人 : 外部导入]
时间限制 : 1.000 sec 内存限制 : 128 MB
题目描述
哈弗曼编码大家一定很熟悉吧(不熟悉也没关系,自己查去。。。)。现在给你一串字符以及它们所对应的权值,让你构造哈弗曼树,从而确定每个字符的哈弗曼编码。当然,这里有一些小规定:
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
2 实现代码
#include
#include
#include
#include
using std::swap;
using std::strcpy;
typedef char *HuffmanCode;
const int MAXN = 110;
typedef struct{
int weight;
char character;
}Key;
typedef struct{
Key key;
int lchild, rchild, parent;
}HuffmanNode, *HuffmanTree;
void selectMin(HuffmanTree HT, int n, int &s1, int &s2){
int min = INT_MAX;
for (int i = 1; i <= n; ++i) {
if(HT[i].parent == 0 && HT[i].key.weight <= min){
if(min > HT[i].key.weight){
min = HT[i].key.weight;
s1 = i;
}else{
if(HT[s1].key.character > HT[i].key.character){
s1 = i;
}
}
}
}
min = INT_MAX;
for (int i = 1; i <= n; ++i) {
if(HT[i].parent == 0 && HT[i].key.weight <= min && i != s1){
if(HT[i].key.weight < min){
min = HT[i].key.weight;
s2 = i;
}else{
if(HT[s2].key.character > HT[i].key.character){
s2 = i;
}
}
}
}
// if(s1 > s2){
// swap(s1, s2);
// }
}
void HuffmanCoding(HuffmanTree &HT, HuffmanCode *&HC, Key w[], int n){
if(n <= 1) return;
int m = 2 * n -1;
HT = new HuffmanNode[m + 1];
for (int i = 1; i <= n; ++i) {
HT[i].key = w[i];
HT[i].lchild = HT[i].rchild = HT[i].parent = 0;
}
for (int i = n + 1; i <= m; ++i) {
HT[i].lchild = HT[i].rchild = HT[i].parent = 0;
}
for (int i = n + 1; i <= m; ++i) {
int s1, s2;
selectMin(HT, i - 1, s1, s2);
HT[s1].parent = HT[s2].parent = i;
HT[i].lchild = s1;
HT[i].rchild = s2;
HT[i].key.character = HT[s1].key.character;
HT[i].key.weight = HT[s1].key.weight + HT[s2].key.weight;
}
HC = new HuffmanCode[n + 1];
char *cd = new char[n];
cd[n -1] = '\0';
for (int i = 1; i <= n; ++i) {
int star = n - 1;
for (int c = i, f = HT[i].parent; f != 0 ; c = f, f = HT[f].parent) {
if(HT[f].lchild == c){
cd[--star] = '0';
}else{
cd[--star] = '1';
}
HC[i] = new char[n - star];
strcpy(HC[i], cd + star);
}
}
delete []cd;
}
int main(){
int n;
Key data[MAXN];
HuffmanTree HT;
HuffmanCode *HC;
while(scanf("%d", &n) != EOF){
for (int i = 1; i <= n; ++i) {
// getchar();
scanf("%*c%c %d", &data[i].character, &data[i].weight);
}
HuffmanCoding(HT, HC, data, n);
for (int i = 1; i <= n; ++i) {
printf("%c:%s\n", data[i].character, HC[i]);
}
delete(HT);
delete(HC);
}
return 0;
}