数据结构-哈夫曼树的实现(C语言+部分注释)

什么是哈夫曼树?

首先我们要介绍一个概念--带权路径长度

而我们的的哈夫曼树的作用即是保证所有叶子结点的带权路径长度最小

:

那么?怎么做到呢;

我们直接说结论:

哈夫曼编码

代码实现

接口

#include <stdio.h>
#include <stdlib.h>
typedef struct treeNode {
	int weight;
	int parent;
	int lchild;
	int rchild;
}treeNode;
typedef struct huffmanTree {
	treeNode* data;
	int length;
}hfTree;
hfTree* hfTreeInit(int* weight, int length);
int* selectMin(hfTree* T) ;
void creatHuffmanTree(hfTree* T);
void preOrder(hfTree* T, int index);

接口实现

hfTree* hfTreeInit(int* weight, int length) {
	hfTree* T = (hfTree*)malloc(sizeof(hfTree));
	T->data = (treeNode*)malloc(sizeof(treeNode) * (2 * length - 1));//由n个结点形成的哈夫曼树有2n-1个结点
	T->length = length;
	for (int i = 0; i < length; i++) {
		T->data[i].weight = weight[i];
		//-1代表没有孩子
		T->data[i].lchild = -1;
		T->data[i].rchild = -1;
		T->data[i].parent = 0;
	}
	return T;
}
int* selectMin(hfTree* T) {
	int min = 10000;
	int secondMin = 10000;
	int minIndex = 0;
	int secondIndex = 0;
	for (int i = 0; i < T->length; i++) {
		if (T->data[i].parent == 0) {
			if (T->data[i].weight < min) {
				min = T->data[i].weight;
				minIndex = i;
			}
		}
	}
	for (int i = 0; i < T->length; i++) {
		if (T->data[i].parent == 0 && i != minIndex) {
			if (T->data[i].weight < secondMin) {
				secondMin = T->data[i].weight;
				secondIndex = i;
			}
		}
	}
	int* res = (int*)malloc(sizeof(int) * 2);//接收索引

	res[0] = minIndex;
	res[1] = secondIndex;
	return res;
}
void creatHuffmanTree(hfTree* T) {
	int length = T->length * 2 - 1;//边界
	int* res;
	int min = -1;
	int secondMin = -1;
	for (int i = T->length; i < length; i++) {
		//因为数组中已经存放了初始的T->length的值,所以下标从T->length开始
		res = selectMin(T);
		//获得索引
		min = res[0];
		secondMin = res[1];
		T->data[i].weight = T->data[min].weight + T->data[secondMin].weight;
		T->data[i].parent = 0;
		T->data[min].parent = i;
		T->data[secondMin].parent = i;
		T->data[i].lchild = min;
		T->data[i].rchild = secondMin;
		T->length++;
	}
}
void preOrder(hfTree* T, int index) {
	if (index != -1) {
		//因为树结点都储存在一个数组中,我们通过下标访问,
		printf("%d ", T->data[index].weight);
		preOrder(T, T->data[index].lchild);
		preOrder(T, T->data[index].rchild);
	}
}

测试

int main() {
	int weight[5] = { 1,2,3,4,5 };
	hfTree* T = hfTreeInit(weight, 5);
	creatHuffmanTree(T);
	preOrder(T, T->length - 1);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

1YC..

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

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

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

打赏作者

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

抵扣说明:

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

余额充值