哈夫曼树的应用
要传输一则报文内容如下:
“AAAAAAAAAAAAAAABBBBBBBBBCCCCCCCCDDDDDDDDDDDDEEEEEEEEEEFFFFF”
请为这段报文设计哈夫曼编码,要求如下:
- 请计算出每个字符出现的概率,并以概率为权重来构造哈夫曼树,写出构造过程、画出
最终的哈夫曼树,得到每个字符的哈夫曼编码。 - 请将上述设计哈夫曼编码的过程,用代码来实现,并输出各个字母的哈夫曼编码。(有
代码,有运行结果的截图
#include <stdio.h>
#include <string.h>
#define max 105
#define MAXLEAF 6 /*定义哈夫曼树中叶子结点的个数*/
#define MAXNODE MAXLEAF*2-1//n个叶子节点的哈夫曼有2n-1个结点
typedef struct {
int weight;//权重
int parent, lchild, rchild;//双亲,左、右孩子
}htnode;
typedef struct Code
{
int bits[MAXLEAF];
int start;
char ch;
}HCodeType;/*定义编码结构*/
htnode tree[MAXNODE];
HCodeType HuffCode[MAXLEAF];
void creathuffmantree(int n, int weight[]);
void Huffmancode();
int main()
{
char str[100];
printf("请输入报文内容:");
gets(str);
//printf("\n");
int time[100];
int weight[100];
int n = MAXLEAF;
for (int j = 0; j < n; j++)//初始化
{
time[j] = 0;
}
for (int i = 0; i < strlen(str); i++)//判断个数
{
switch (str[i])
{
case'A':time[0]++;
break;
case'B':time[1]++;
break;
case'C':time[2]++;
break;
case'D':time[3]++;
break;
case'E':time[4]++;
break;
case'F':time[5]++;
break;
}
}
double sum = 0;
for (int k = 0; k < n; k++) //计算权值
{
sum = sum + time[k];
}
for (int l = 0; l < n; l++)
{
weight[l] = (time[l] / sum) * 100;
}
creathuffmantree(n, weight);
Huffmancode();
}
void creathuffmantree(int n, int weight[])
{
if (n < 1) return;
for (int i = 0; i < MAXNODE; i++)
{
tree[i].parent = -1;
tree[i].lchild = -1;
tree[i].rchild = -1;
}
for (int j = 0; j < n; j++) {
tree[j].weight = weight[j];
}
//---------------------------------------------------初始化
for (int k = MAXLEAF; k < MAXNODE; k++)
{
int m1 = max, m2 = max, s1=0, s2=0;
for (int i = 0; i < k; i++)//选择两个最小的权值,且双亲域为0
{
if (tree[i].weight < m1 && tree[i].parent == -1)
{
m2 = m1; s2 = s1;
m1 = tree[i].weight;
s1 = i;
}//m1最小,s1为其位置
else if (tree[i].weight < m2 && tree[i].parent == -1)
{
m2 = tree[i].weight;
s2 = i;
}//m2次小,s2为其位置
}
tree[s1].parent = k;
tree[s2].parent = k;//得到新结点
tree[k].lchild = s1;
tree[k].rchild = s2;//新结点孩子
tree[k].weight = tree[s1].weight + tree[s2].weight;//新结点权重
}
}
void Huffmancode()
{
int c, p, i, j;
for (i = 0; i < MAXLEAF; i++)
{
HuffCode[i].start = MAXLEAF;
printf("请输入字符:");
scanf("%c",&HuffCode[i].ch);
getchar();
c = i;
p = tree[i].parent;
while (p != -1)//到根节点
{
HuffCode[i].start--;//从数组后面往前记录
if (tree[p].lchild == c)
{
HuffCode[i].bits[HuffCode[i].start] = 0;//c是p的左孩子为0
}
else
{
HuffCode[i].bits[HuffCode[i].start] = 1;//右孩子为1
}
c = p;//c向上走
p = tree[p].parent;//p向上走
}
}
for (i = 0; i < MAXLEAF; i++)/*输出字符、权值及编码*/
{
printf("字符 %c 权值 %d,编码是:", HuffCode[i].ch, tree[i].weight);
for (j = HuffCode[i].start; j < MAXLEAF; j++)
printf(" %d ", HuffCode[i].bits[j]);
printf("\n");
}
}