数据结构---哈夫曼树

本文详细介绍了哈夫曼树的构建过程及其在数据压缩中的应用,通过C语言实现哈夫曼编码,并提供了完整的代码示例。程序首先读取字符及其权重,然后构造哈夫曼树并寻找每个字符的哈夫曼编码。最后,计算了所有字符的编码长度之和,展示了哈夫曼编码的时间复杂度为O(n^2)和空间复杂度为O(n)。对于理解哈夫曼编码的原理和实现具有指导意义。
摘要由CSDN通过智能技术生成

数据结构—哈夫曼树

原理:参考趣学数据结构

代码:

#include<stdio.h>
#include<stdlib.h>
#define N 100
#define INF 2^31-1
typedef struct fNode {//哈夫曼树中每个节点的信息
	int c;//字符
	int parent;//父节点,左右孩子,权重
	int lchild, rchild;
	int weight;
}fNode;
typedef struct rNode {//存储单个的编码字符的编码序列
	int r[N];
	int start;//有效编码起始的位置
	int length;
}rNode;
void huffMan(fNode fnode[],int n) {//构造哈夫曼树  选取二个最小的没有父节点的结点合并,以此类推
	for (int i = 0; i < n - 1; i++) {//n个字符n-1次的构造即可构造哈夫曼树
		int min1=INF, min2 = INF;
		int u =-1,v = -1;
		for (int j = 0; j < n + i; j++) {//找二个最小的没有父节点的
			if (fnode[j].weight < min1 && fnode[j].parent==-1) {
				min2 = min1;//最值同时往前推
				v = u;
				min1 = fnode[j].weight;
				u = j;
			}
			else if(fnode[j].weight<min2 && fnode[j].parent == -1) {
				min2 = fnode[j].weight;
				v = j;
			}
		}
		fnode[n + i].weight = min1 + min2;
		fnode[n + i].lchild = u;
		fnode[n + i].rchild = v;
		fnode[u].parent = fnode[v].parent = n + i;//更新父节点
	}
}
void findHuffManCodePath(fNode fnode[],rNode rnode[],int n) {//寻找每个字符编码表示
	rNode temp;
	int start=n-1;//最坏的哈夫曼树为一条链表
	for (int i = 0; i < n; i++) {
		start = n - 1;
		//每个字符的编码从叶子节点向根节点遍历
		int p = fnode[i].parent;
		int tempv = i;
		while (p != -1) {//p不等于-1表示有父节点
			if (tempv == fnode[p].lchild) {
				temp.r[start] = 0;
			}
			else {
				temp.r[start] = 1;
			}
			start--;
			tempv = p;
			p = fnode[p].parent;
		}
		for (int j = start + 1; j <= n - 1; j++) {//更新每个字符的编码数组
			rnode[i].r[j] = temp.r[j];
			rnode[i].start = start + 1;
		}
		rnode[i].length = n - start - 1;
	}
	int sum = 0;
	//遍历每个字符的编码数组
	for (int j = 0; j < n; j++) {//n个字符的编码遍历
		printf("%d的哈夫曼编码为:", fnode[j].c);
		for (int k = rnode[j].start; k <= n - 1; k++) {
			printf("%d", rnode[j].r[k]);
		}
		sum += (fnode[j].weight*rnode[j].length);
		printf("  ");
	}
	printf("\n");
	printf("哈夫曼编码长度为:%d\n",sum);
	printf("\n");
}
int main() {
	fNode fnode[N];
	rNode rnode[N];
	int u;
	printf("请输入编码字符的个数:");
	scanf_s("%d", &u);
	int length = u;
	int c;
	int weight=0;
	//http://c.biancheng.net/view/1796.html 输入字符参考
	for (int k = 0; k < u;k++) {//初始化字符编码的信息 
		//c = getchar();//输入字符
		scanf_s("%d %d", &c,&weight);
		fnode[k].c = c;
		fnode[k].weight = weight;
	}
	u = 2 * length - 1;//哈夫曼总共有2n-1个结点
	for(int i=0;i<u;i++){//初始化结点的左右孩子和父节点信息
		fnode[i].lchild = -1;
		fnode[i].rchild = -1;
		fnode[i].parent = -1;
	}
	huffMan(fnode, length);
	findHuffManCodePath(fnode, rnode, length);
	system("pause");
	return 0;
}

测试截图:

请添加图片描述

时间复杂度O(n x n),空间复杂度O(n)

如果存在什么问题,欢迎批评指正!谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fighting的码农(zg)-GPT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值