#include<stdio.h>
#include<algorithm>
#define N 1000
#define M 2 * N - 1
typedef struct {
int weight;
int parent;
int Lchild;
int Rchild;
}HTNode, HuffmanTree[N + 1];
typedef struct {
char data[N];
char code[N][10 * N];
}Code;
void select(HuffmanTree ht, int end, int * s1, int * s2)
{
int min1, min2, a, b;
int i = 1, j;
while (ht[i].parent != 0)
{
i++;
}
min1 = ht[i].weight;
a = i;
for (j = i + 1; j <= end; j++)
{
if (min1 > ht[j].weight && ht[j].parent == 0)
{
min1 = ht[j].weight;
a = j;
}
}
i = 1;
while (ht[i].parent != 0 || a == i)
{
i++;
}
min2 = ht[i].weight;
b = i;
for (j = i + 1; j <= end; j++)
{
if (j == a)
continue;
if (min2 > ht[j].weight && ht[j].parent == 0)
{
min2 = ht[j].weight;
b = j;
}
}
*s1 = a; *s2 = b;
}
void creatHuffman(HuffmanTree ht, int w[], int n)
{
int s1, s2;
int t;
for (t = 1; t <= n; t++)
{
ht[t].weight = w[t - 1];
ht[t].parent = 0;
ht[t].Lchild = 0;
ht[t].Rchild = 0;
}
for (t = n + 1; t <= 2 * n - 1; t++)
{
ht[t].weight = 0;
ht[t].parent = 0;
ht[t].Lchild = 0;
ht[t].Rchild = 0;
}
for (t = n + 1; t <= 2 * n - 1; t++)
{
select(ht, t - 1, &s1, &s2);//前i-1中选双亲为0, 权值最小
ht[t].weight = ht[s1].weight + ht[s2].weight;
ht[t].Lchild = s1, ht[t].Rchild = s2;
ht[s1].parent = t, ht[s2].parent = t;
}
}
int input(int w[], Code * code)
{
int n = 0;
printf("请输入您要进行的编码:");
gets_s(code->data, N);
n = strlen(code->data);
for (int i = 0; i < n; i++)
{
w[i] = 1;
for (int j = i + 1; j < n;)
{
if (code->data[i] == code->data[j])
{
w[i]++;
for (int k = j; k<n; k++)
{
code->data[k] = code->data[k + 1];
}
n--; //覆盖完之后n--;
}
else
j++;
}
}
printf("不同的字符为:");
for (int i = 0; i<n; i++)
{
printf("%c", code->data[i]);
}
putchar('\n');
return n;
}
void Encode(HuffmanTree ht, Code * code, int n)
{
char * cd;
int start;
int c, p;
cd = (char*)malloc(n * sizeof(char));
cd[n - 1] = '\0';
for (int i = 1; i <= n; i++) {
start = n - 1; c = i;
p = ht[i].parent;
while (p != 0) {
--start;
if (ht[p].Lchild == c) {
cd[start] = '0';
}
else {
cd[start] = '1';
}
c = p; p = ht[p].parent;
}
strcpy(code->code[i - 1], &cd[start]);
}
free(cd);
}
void Decode(HuffmanTree ht, Code * code, int n)
{
char s[10 * N];
int p;
printf("请输入要译码的字符:");
gets_s(s, 10 * N);
printf("译码为:");
p = 2 * n - 1;
int i = 0;
for (i = 0; s[i] != '\0'; i++)
{
if (s[i] == '0')
p = ht[p].Lchild;
else if (s[i] == '1')
p = ht[p].Rchild;
if (ht[p].Lchild == 0 && ht[p].Rchild == 0)
{
printf("%c", code->data[p - 1]);//p: 1~~2*n-1, bbm->data[0~~n-1]
p = 2 * n - 1;
continue;
}
}
putchar('\n');
return;
}
void output(Code * code, int n)
{
printf("\n");
for (int i = 0; i<n; i++)
{
printf("%c\t", code->data[i]);
printf("%s\n", code->code[i]);
}
}
int main(void)
{
HuffmanTree ht;
Code * code = (Code *)malloc(sizeof(Code));
int w[N];
int n = input(w, code);
printf("不同的字符总数有%d种\n", n);
creatHuffman(ht, w, n);
Encode(ht, code, n);
output(code, n);
Decode(ht, code, n);
return 0;
}
哈夫曼树的创建及其编译码
最新推荐文章于 2024-04-27 12:09:00 发布