哈夫曼树(C语言实现)

本文深入探讨了哈夫曼树的基本概念,包括路径、路径长度、带权路径长度等,并详细介绍了如何构建哈夫曼树。通过选取最小权值结点合并的方式,逐步构建出最优二叉树。同时,文章还阐述了哈夫曼编码的生成过程,通过从根结点到叶子结点的路径确定编码。最后,提供了完整的C语言代码实现,展示了构建哈夫曼树和编码的具体步骤。

哈夫曼树的基本概念

在认识哈夫曼树之前,你必须知道以下几个基本术语:
1、什么是路径?

在一棵树中,从一个结点往下可以达到的结点之间的通路,称为路径。

在这里插入图片描述
如图,从根结点A到叶子结点I的路径就是A->C->F->I

2、什么是路径长度?

某一路径所经过的“边”的数量,称为该路径的路径长度

在这里插入图片描述
如图,该路径经过了3条边,因此该路径的路径长度为3

3、什么是结点的带权路径长度?

若将树中结点赋给一个带有某种含义的数值,则该数值称为该结点的权。从根结点到该结点之间的路径长度与该结点的权的乘积,称为该结点的带权路径长度。

在这里插入图片描述
如图,叶子结点I的带权路径长度为  3 × 3 = 9 3\times3=9 3×3=9

4、什么是树的带权路径长度?

树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。

在这里插入图片描述
如图,该二叉树的带权路径长度 WPL = 2 × 2 + 2 × 6 + 3 × 1 + 3 × 3 + 2 × 2 = 32 =2\times 2 + 2 \times 6 + 3 \times 1 + 3 \times 3 + 2 \times 2 = 32 =2×2+2×6+3×1+3×3+2×2=32

5、什么是哈夫曼树?

给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,则称该二叉树为哈夫曼树,也被称为最优二叉树。

根据树的带权路径长度的计算规则,我们不难理解:树的带权路径长度与其叶子结点的分布有关。
即便是两棵结构相同的二叉树,也会因为其叶子结点的分布不同,而导致两棵二叉树的带权路径长度不同。
在这里插入图片描述
那如何才能使一棵二叉树的带权路径长度达到最小呢?
 根据树的带权路径长度的计算规则,我们应该尽可能地让权值大的叶子结点靠近根结点,让权值小的叶子结点远离根结点,这样便能使得这棵二叉树的带权路径长度达到最小。

哈夫曼树的构建

构建思路

下面给出一个非常简洁易操作的算法,来构造一棵哈夫曼树:
1、初始状态下共有n个结点,结点的权值分别是给定的n个数,将他们视作n棵只有根结点的树。
2、合并其中根结点权值最小的两棵树,生成这两棵树的父结点,权值为这两个根结点的权值之和,这样树的数量就减少了一个。
3、重复操作2,直到只剩下一棵树为止,这棵树就是哈夫曼树。

例如,现给定5个数,分别为1、2、2、3、6,要求构建一棵哈夫曼树。
动图演示:
在这里插入图片描述
1、初始状态:有5棵只有根结点的树。
在这里插入图片描述
2、合并权值为1和2的两棵树,生成这两棵树的父结点,父结点权值为3。
在这里插入图片描述
3、合并权值为2和3的两棵树,生成这两棵树的父结点,父结点权值为5。
在这里插入图片描述
4、合并权值为3和5的两棵树,生成这两棵树的父结点,父结点权值为8。
在这里插入图片描述
5、合并权值为6和8的两棵树,生成这两棵树的父结点,父结点权值为14。
在这里插入图片描述
6、此时只剩下一棵树了,这棵树就是哈夫曼树。
在这里插入图片描述
观察这棵哈夫曼树,我们还可以发现,哈夫曼树不存在度为1的结点。因为我们每次都是选择两棵树进行合并,自然不存在度为1的结点。
由此我们还可以推出,若给定n个数要求构建哈夫曼树,则构建出来的哈夫曼树的结点总数为2n-1,因为对于任意的二叉树,其度为0的叶子结点个数一定比度为2的结点个数多1。

证明:
  设度为0,1,2的结点个数分别为n0,n1,n2
  则二叉树的总结点数 n = n 0 + n 1 + n 2 n=n0+n1+n2 n=n0+n1+n2
  设二叉树中边的条数为B
  则 B = n 2 × 2 + n 1 × 1 B=n2\times2+n1\times1 B=n2×2+n1×1
  又 ∵ B = n − 1 \because B=n-1 B=n1
   ∴ n 2 × 2 + n 1 = n − 1 \therefore n2\times2+n1=n-1 n2×2+n1=n1
  即 n = n 2 × 2 + n 1 + 1 n=n2\times2+n1+1 n=n2×2+n1+1
  

评论 132
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

2021dragon

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

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

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

打赏作者

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

抵扣说明:

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

余额充值