测试用例:
7
h1
e1
l3
o2
w1
r1
d1
000001101011101011101110110
期望输出:
h:000
e:001
w:010
r:011
l:10
d:110
o:111
helloworld
节点 | 权值 | parent | 左孩子 | 右孩子 | 字符 |
---|
1 | 1 | 8 | 0 | 0 | h |
2 | 1 | 8 | 0 | 0 | e |
3 | 3 | 12 | 0 | 0 | l |
4 | 2 | 10 | 0 | 0 | o |
5 | 1 | 9 | 0 | 0 | w |
6 | 1 | 9 | 0 | 0 | r |
7 | 1 | 10 | 0 | 0 | d |
8 | 2 | 11 | 1 | 2 | |
9 | 2 | 11 | 5 | 6 | |
10 | 3 | 12 | 7 | 4 | |
11 | 4 | 13 | 8 | 9 | |
12 | 6 | 13 | 3 | 10 | |
13 | 10 | 0 | 11 | 12 | |
代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define N 30
#define Max (2 * N - 1)
typedef struct {
double weight;
char s;
int parent,lchild,rchild;
}HTNode,HuffmanTree[Max+1];
void Select(HuffmanTree ht,int j,int *m1,int *m2);
void CreatHuffmanTree(HuffmanTree ht,int n);
void HuffmanCoding(HuffmanTree ht, char **hc, int n);
void printHuffmanCode(HuffmanTree ht,char **hc,int index);
void HuffmanDecoding(HuffmanTree ht,int n, char *pwd);
void Select(HuffmanTree ht,int j,int *m1,int *m2){
double min1 = 9999999;
double min2 = 9999999;
for(int i = 1; i<= j;i++){
if(ht[i].weight < min1 && ht[i].parent == 0){
min1 = ht[i].weight;
*m1 = i;
}
}
for(int i = 1; i<= j;i++){
if(ht[i].weight < min2 && ht[i].parent == 0 && i!=*m1){
min2 = ht[i].weight;
*m2 = i;
}
}
}
void CreatHuffmanTree(HuffmanTree ht,int n){
for (int i = n+1; i <= 2 * n - 1 ; i++) {
int m1,m2;
Select(ht,i-1,&m1,&m2);
ht[i].weight = ht[m1].weight + ht[m2].weight;
ht[i].lchild = m1;
ht[i].rchild = m2;
ht[i].parent = 0;
ht[m1].parent = i;
ht[m2].parent = i;
}
}
void HuffmanCoding(HuffmanTree ht, char **hc, int n){
char *cd = (char*) malloc(n * sizeof(char));
cd[n-1] = '\0';
int now = 1;
int p = 0;
int start;
int i = 0;
while(i < n){
start = n-1;
now = i+1;
p = ht[now].parent;
while(p != 0){
start--;
if(ht[p].lchild == now){
cd[start] = '0';
} else{
cd[start] = '1';
}
now = p;
p = ht[now].parent;
}
hc[i+1] = (char*) malloc((n-start)* sizeof(char));
strcpy(hc[i+1],&cd[start]);
i++;
}
}
void printHuffmanCode(HuffmanTree ht,char **hc,int index){
if(index >= 1){
if(ht[index].lchild == 0 && ht[index].rchild == 0){
printf("%c:%s\n",ht[index].s,hc[index]);
return;
}
printHuffmanCode(ht,hc,ht[index].lchild);
printHuffmanCode(ht,hc,ht[index].rchild);
}
}
void HuffmanDecoding(HuffmanTree ht,int n, char *pwd){
printf("译码:");
int len = strlen(pwd);
int i = 0;
int node = 2 * n-1;
while(i < len){
if(pwd[i] == '0'){
node = ht[node].lchild;
i++;
if(ht[node].lchild == 0 && ht[node].rchild == 0){
printf("%c",ht[node].s);
node = 2*n-1;
}
}
if(pwd[i] == '1'){
node = ht[node].rchild;
i++;
if(ht[node].rchild == 0 && ht[node].rchild == 0){
printf("%c",ht[node].s);
node = 2*n-1;
}
}
}
}
int main() {
HuffmanTree ht;
int n;
printf("多少个字符:");
scanf("%d",&n);
getchar();
char *hc[n+1];
for (int i = 1; i <= n ; i++) {
scanf("%c%lf",&ht[i].s,&ht[i].weight);
getchar();
ht[i].lchild = 0;
ht[i].rchild = 0;
ht[i].parent = 0;
}
char pwd[9999];
scanf("%s",pwd);
CreatHuffmanTree(ht,n);
HuffmanCoding(ht,hc,n);
printHuffmanCode(ht,hc,2*n-1);
HuffmanDecoding(ht,n,pwd);
return 0;
}