[C语言]哈夫曼树的基本操作

本文介绍了哈夫曼树的基本概念,如路径长度、带权路径长度和带权路径长度最小的二叉树——哈夫曼树。通过结构体、构建空堆、调整最小堆等步骤详细阐述了如何构建哈夫曼树,并提供了算法实现,以达到提高查找效率的目的。
摘要由CSDN通过智能技术生成

概念

  1. 路径长度:从树中一个节点到另一个节点之间的分支构成两个节点之间的路径,路径上分支的数目称为路径长度.
  2. 树的路径长度:从树根到每一节点的路径长度之和
    在这里插入图片描述
    这个树的路径长度就是16
  3. 节点的带权路径长度: 从该节点到树根之间的路径长度与节点上权的乘积
  4. 树的带权路径长度(WPL): 树的每个叶子节点的带权路径之和
    以上图为例
    这棵树的WPL就是3*5+15*3+40*2+30*2+10*2 = 220
    而另一种结构的树的路径长度却如此大,显然总的查找效率没有上一个高
    在这里插入图片描述
  5. WPL最小的二叉树称为哈夫曼树(最优二叉树)
  6. 哈夫曼树算法:
    1. 根据给定的n个权值{ Wl,W2...Wn }构成n棵二叉树的集合F={ T1,T2...Tn }, 其中每棵二叉树T:中只有一个带权为W的根结点,其左右子树均为空.
    2. 在F中选取两棵根结点的权值最小的树作为左右子树构造一棵新的二叉树,且新的二叉树的根结点的权值为其左右子树上根结点的权值之和.
    3. 在F中删除这两棵树,同时将新得到的二叉树加入F中。
    4. 重复2和3步骤,直到F只含一棵树为止。这棵树便是哈夫曼树。

所以我们可以采用最小堆的方法来构建哈夫曼树

结构体

typedef int DataType; //权重类型

typedef struct HuffmanNode
{
   
	DataType wight;	//权重
	struct HuffmanNode *left,*right;  //左右孩子
} HNode;  //哈夫曼树节点的结构体

typedef struct HuffmanList
{
   
	HNode** data;  //存树头指针的数组
	int nowsize,maxsize;  //目前节点数和最大值
} HList;  //存放树节点的最小堆结构体

构建空堆

//创建空堆
HList* CreatHeap()
{
   
	HList* H = (HList*)malloc(sizeof(HList));
	H->data = (HNode**)malloc(sizeof(HNode*)*(MAXSIZE+1));//开辟数组空间
	H->nowsize = 0;
	H->maxsize = MAXSIZE;
	H->data[0] = (HNode*)malloc(sizeof(HNode));
	H->data[0]->wight = MINDATA;  //哨兵节点
	return H;
}

判空判满

int IsFull(HList *H)//判满
{
   
	return H->nowsize==H->maxsize;
}

int IsEmpty(HList *H)//判空
{
   
	return H->nowsize == 0;
}

向下调整以及构建最小堆

void Swap(HList *H,int a,int b)//交换H中两个节点
{
   
	HNode* temp = H->data[a];
	H->data[a] = H->data[b];
	H->data[b] = temp;
}

void SiftDown(HList* H,int num,int size)//单个节点向下调整
{
   
	int t,flag = 0;
	while(num*2 <= size && flag == 0)
	{
   
		t = H->data[num]->wight<H->data[num*2]->wight?num:num*2;
		if(num*2+1<=size)
			t = H->data[t]->wight<H->data[num*2+1]->wight?t:num*2+1;
		if(num == t)
			flag = 1;
		else
			Swap(H,num,t);
		num = t;
	}
}

void MinHeap(HList* H)//构建最小堆
  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值