数据结构与C语言实现(五)——树(下):哈夫曼树与哈夫曼编码

/*
哈弗曼树的定义
带权路径长度:设二叉树有n个叶子节点,每个叶子节点带有权值Wk,从根节点到每个椰子节点的长度为Lk
则每个叶子节点的带权路径的长度之和就是每个wk*lk之后加起来

最优二叉树或者哈夫曼树:WPL最小的二叉树
*/
#include <stdio.h>
#include <stdlib.h>

//哈弗曼树的构造——每次把权值最小的两个树合并
#define MAXSIZE 100
typedef struct TreeNode* HuffmanTree;
struct TreeNode
{
	int Weight;
	HuffmanTree left, right;
};
struct HeapNode
{
	HuffmanTree data[MAXSIZE];
	int size;
	int MaxSize;
};
typedef struct HeapNode* MinHeap;

//堆的实现,建立最小堆
void BuildMinHeap(MinHeap H)
{
	int parent, child, temp;
	int i;
	H->data[0]->Weight = -1;//哨兵
	for (i = H->size / 2; i > 0; i--)//从深度倒数第二的位置从后向前走
	{
		temp = H->data[i]->Weight;
		for (parent = i; parent * 2 <= H->size; parent = child)
		{
			//下面寻找最小的儿子
			child = parent * 2;//找到爸爸节点的儿子
			if ((child != H->size) && (H->data[child + 1]->Weight < H->data[child]->Weight))
				child++;//如果说右儿子比左儿子要小,那么左儿子胜出。因为我们这里建立的是最小堆。
			//下面进行替换
			if (temp <= H->data[child]->Weight) break;
			else
			{
				H->data[parent]->Weight = H->data[child]->Weight;
			}
		}
		H->data[parent]->Weight = temp;
	}
}

//堆的删除最小值操作
HuffmanTree DeleteMin(MinHeap H)
{
	int parent, child;
	int temp;
	//第一步,先把堆的根部拿走
	HuffmanTree ans = H->data[H->size--];//将ans的值保存起来
	temp = H->data[H->size]->Weight;//将下标最大的那个取出来,放在第一个,准备依次向下寻找,小的就上来,大的就下去
	for (parent = 1; parent * 2 <= H->size; parent = child)
	{
		//下面寻找最小的儿子
		child = parent * 2;//找到爸爸节点的儿子
		if ((child != H->size) && (H->data[child + 1]->Weight < H->data[child]->Weight))
			child++;//如果说右儿子比左儿子要小,那么左儿子胜出。因为我们这里建立的是最小堆。
					//下面进行替换
		if (temp <= H->data[child]->Weight) break;
		else
		{
			H->data[parent]->Weight = H->data[child]->Weight;
		}
	}
	H->data[parent]->Weight = temp;
	return ans;
}

//最小堆的插入.插入一定要从下往上插入
void Insert(HuffmanTree Item,MinHeap H)
{
	int i;
	H->size++;
	for (i = H->size; H->data[i/2]->Weight > Item->Weight; i/=2)//当父亲比插入值大的时候,就一直循环
	{
		H->data[i]->Weight = H->data[i/2]->Weight;//父亲比插入值要大,那么父亲就要走到下面去
		//儿子节点   //父亲的值
	}
	H->data[i / 2]->Weight = Item->Weight;

}

HuffmanTree Huffman(MinHeap H)
{
	HuffmanTree T;//最后返回的是哈夫曼树
	int i;
	BuildMinHeap(H);//先创建一个堆树
	for (i = 1; i < H->size; i++)
	{
		T = (HuffmanTree)malloc(sizeof(struct TreeNode));
		T->left = DeleteMin(H);//从堆树中弹出一个最小的放到T的左边
		T->right = DeleteMin(H);//从堆树中弹出一个最小的放到T的右边
		T->Weight = T->left->Weight + T->right->Weight;
		Insert(T, H);
	}
	T = DeleteMin(H); 
	return T;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值