C语言 哈弗曼树 数据结构

哈夫曼树的应用

要传输一则报文内容如下:
“AAAAAAAAAAAAAAABBBBBBBBBCCCCCCCCDDDDDDDDDDDDEEEEEEEEEEFFFFF”
请为这段报文设计哈夫曼编码,要求如下:

  1. 请计算出每个字符出现的概率,并以概率为权重来构造哈夫曼树,写出构造过程、画出最终的哈夫曼树,得到每个字符的哈夫曼编码。
  2. 请将上述设计哈夫曼编码的过程,用代码来实现,并输出各个字母的哈夫曼编码。(有代码,有运行结果的截图)

(1) 由上述这段编码可得,ABCDEF的概率分别为:15/59、9/59、8/59、12/59、10/59、5/59。
构造哈夫曼树的目的是找出存放一串字符所需的最少的二进制编码,其构造过程就是:找出结点权值中最小的两个,把这两个作为左右子树构造成一棵新的二叉树,二叉树根结点的值就是其左右子树根结点权值之和,在森林中删除此次找到的两个数,并加入此次最小两个数的和,不断重复这一过程,直到树中只含有一棵树为止。
构造过程如图所示
在这里插入图片描述
最终的结果如图所示:
在这里插入图片描述
每个字符的编码依次为:
A:10 B:110 C:011 D:00 E:111 F:010

(2)代码为:

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define ERROR 0
typedef struct HTNode
{
	int weighted;//权重
	int Parents;//双亲
	int Lchild, Rchild;//左右孩子
};
typedef HTNode * huffman;
typedef char** haffmancode;
void chushihua(huffman& T, int num)//初始化工作 num是结点个数
{
	int length = num * 2 - 1;
	int i;
	int j;
	int legth=length+1;
	T = (huffman)malloc((legth + 1) * sizeof(HTNode));
	for (i = 1; i <= length; i++)
	{
		T[i].Parents = ERROR;//初始化 ERROR=0
		T[i].Rchild = ERROR;//初始化 ERROR=0
		T[i].Lchild = ERROR;//初始化 ERROR=0
	}
	printf("请输入每个叶子的权值\n");
	for (j = 1; j <=num; j++)
	{
		scanf("%d", &T[j].weighted);//初始化
	}
}

void creat(huffman &T,int num)//构造haffman树
{
	int i;
	int j;
	int p, q;
	int m1, m2;
	if (num < 2)
	{
		printf("ERROR\n");
		return;
	}
	chushihua(T, num);
	int s1, s2;
	for (i = num+1; i <2 * num ; i++)
	{
		m1 = 10000000;//定义最大量
		m2 = m1;
		p = q = 0;
		for (j = 0; j < i; j++)
		{
			if (T[j].weighted < m1 && T[j].Parents == ERROR)
			{
				m2 = m1; q = p;
				m1 = T[j].weighted;
				p = j;
			}
			else if(T[j].weighted < m2 && T[j].Parents == ERROR)
			{
				m2 = T[j].weighted;
				q = j;
			}
		}
		T[p].Parents = i;
		T[q].Parents = i;
		T[i].Lchild = p;
		T[i].Rchild = q;
		T[i].weighted = T[p].weighted + T[q].weighted;
	}
}
typedef struct
{
	char ch;
	char bits[10];
}CodeNode;
typedef CodeNode* HuffmanCode;
void lasthuffman(huffman T,haffmancode &t,int num)//编码
{
	t= (char**)malloc((num+1) * sizeof(char*));
	char* ch = (char*)malloc(num * sizeof(char));
	ch[num - 1] = '\0';
	int i;
	int m;
	int point;
	int result;
	for (i = 1; i <=num; i++)
	{
		m = num - 1;
		point = i;
		result = T[i].Parents;
		while (result!=0)
		{
			m--;
			if (T[result].Lchild == point)
			{
				ch[m] = '0';
			}
			else
			{
				ch[m] = '1';
			}
			point = result;
			result = T[result].Parents;
		}
		t[i] = new char[num - m];
		strcpy(t[i], &ch[m]);
	}
	delete ch;
}
int main()
{
	int num;
	printf("请输入结点的个数:");
	scanf("%d", &num);
	huffman T;
	creat(T, num);
	haffmancode t;
	printf("请输入各点字符\n");
	char ch[1000];
	getchar();
	for (int k = 0; k < num; k++)
	{
		scanf("%c", &ch[k]);
	}
	lasthuffman(T, t, num);
	for (int i = 1; i <=num; i++)
	{
		printf("%c的前缀编码为:%s\n",ch[i-1],t[i]);
	}
}

运行结果为:
在这里插入图片描述

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值