哈弗曼编码(含代码)

									## 哈弗曼编码
	首先用字符串接受字符,接着遍历,获取每个字符的权值,排序,接着创建静态链表
	有cnt不同的字符,创建2*cnt-1个空间的静态链表
	初始化前cnt项,将权值附上
	后面的进行初始化归0
	接着每次遍历前i-1个节点,每次找权值最小的两个,将父节点定为i
	i的左为最小权值节点 右为次小权值节点
	i的权值为最小和次小之和
	生成二叉树后,逐个遍历前cnt个节点,回到根,用当前节点和父节点进行比较编码
	编码为反序,进行处理获得正序编码
	建立一定对应关系,输出各个字符的编码
	最后遍历字符串,一一对应编码输出
	over
	代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct tree
{
	int weight;
	int parent;
	int lchild;
	int rchild;
};
int judge(char a, char b[2][50], int n);
int count(char a[500], char b, int n);
int main()
{
	char Date[500];
	scanf("%s", &Date);
	int lenth;
	lenth= strlen(Date);
	char a[2][50];
	int cnt = 0;
	for (int i = 0; i < lenth; i++)
	{
		if (judge(Date[i],a,cnt) == 0)
		{
			a[0][cnt] = Date[i];
			a[1][cnt] = count(Date, a[0][cnt], lenth) + '0';
			cnt++;
		}
	}
	a[0][cnt] = '\0';
	a[1][cnt] = '\0';
	for (int i = 0; i < cnt; i++)
	{
		for (int j = 0; j < cnt-i-1; j++)
		{
			if (a[1][j] - '0' > a[1][j + 1] - '0')
			{
				char temp1 = a[0][j];
				char temp2 = a[1][j];
				a[0][j]= a[0][j+1];
				a[1][j]= a[1][j+1];
				a[0][j + 1] = temp1;
				a[1][j + 1] = temp2;
			}
		}
		
	}
	int cnn = 2*cnt-1;
	struct tree hamden[50];
	for (int i = 0; i < cnt; i++)
	{
		hamden[i] = { a[1][i] - '0',0,0,0 };
	}
	for (int i = cnt; i < cnn; i++)
	{
		hamden[i] = { 0,0,0,0 };
	}
	for (int i = cnt; i < cnn; i++)
	{
		int min =0, mmin = 0;
		int min1 = 99, mmin1 = 99;
		for (int j = 0; j < i; j++)
		{
			if (mmin1 > hamden[j].weight && hamden[j].parent == 0)
			{
				mmin = j;
				mmin1 = hamden[j].weight;
			}
			if (min1 > hamden[j].weight && hamden[j].parent == 0)
			{
				if (mmin != j)
				{
					min = j;
					min1 = hamden[j].weight;
				}
			}

		}
		hamden[i].weight = hamden[mmin].weight + hamden[min].weight;
		hamden[i].lchild = mmin;
		hamden[i].rchild = min;
		hamden[mmin].parent = i;
		hamden[min].parent = i;
	}
	for (int i = 0; i < cnn; i++)
	{
		printf("%d %d %d %d\n", hamden[i].weight, hamden[i].parent, hamden[i].lchild, hamden[i].rchild);
	}
	printf("\n");
	char cd[50];
	char res[50][50];
	int u = 0;
	int v = 0;
	for (int i = 0; i < cnt; i++)
	{
		int start= 0;
		int c = i;
		int p = hamden[i].parent;
		v = 0;
		while (p != 0)
		{
			if (hamden[p].lchild == c)
				cd[start] = '0';
			else
				cd[start] = '1';
			c = p;
			p = hamden[p].parent;
			start++;
		}
		cd[start] = '\0';
		int len = strlen(cd);
		for (int i = len - 1; i >= 0; i--)
		{
			res[u][v++] = cd[i];
		}
		res[u++][v] = '\0';
	}
	for (int i = 0; i < cnt; i++)
	{
		printf("%c的编码是: %s\n", a[0][i], res[i]);
	}
	printf("编码后结果:");
	for (int i = 0; i < lenth; i++)
	{
		for (int j = 0; j < cnt; j++)
		{
			if (Date[i] == a[0][j])
			{
				printf("%s", res[j]);
			}
		}
	}
}

int judge(char a, char b[2][50],int n)
{
	int cnt = 0;
	for (int i = 0; i < n; i++)
	{
		if (a == b[0][i])
			cnt++;
	}
	if (cnt == 0)
		return 0;
	else
		return 1;
}
int count(char a[500], char b, int n)
{
	int cnt = 0;
	for (int i = 0; i < n; i++)
	{
		if (a[i] == b)
			cnt++;
	}
	return cnt;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值