C++ 图 的延展 哈夫曼树(四十三)【第九篇】

今天我们来讲一下哈夫曼树

1.哈夫曼树搭建

现在给你这样一个问题:

一棵二叉树上有 n 个叶子结点,每个叶子结点都有一个权值。现在要构造一棵二叉树,树上每条边的权值都是 1,并满足所有 叶子结点权值 和 它到根的 距离的 积 之和sum 最小。

你需要把这棵二叉树画出来:

图片

sum=1×2+2×2+3×1=9

思考一下这棵二叉树怎么建立?

我们先看这样一棵二叉树:

图片

将所有叶子结点权值与它到根的距离的积之和的计算方法转换为计算每条边的贡献,再求和(如右图)。

根据二叉树的性质:
n[0]=2+1,此时还需要求出 n[1] 的值,就可以确定整棵二叉树的结点数量了。因为将问题转换为边权的贡献和,所以需要尽量让边的数量更少,因此 
n[1]=0。

这是因为度数为 
1 的点只会不会影响叶子结点的数量。

图片

因此这样二叉树中结点的数量有n=n[0]+n[2]=2n[0]−1;边的数量有 2n[0]−1。

根据上图的右侧图中可以发现每条边的贡献实际上是该边连接的“下侧”结点的权值,而对于一个非叶子结点的权值是等于它的两个儿子结点的权值和。

现在我们的目的就是让每个结点的权值(边的贡献)尽可能小,因为最初给的均为叶子结点的权值,所以从叶子结点开始构造。

将所有的叶子结点看作一棵子树,每棵子树的权值为该树根结点的权值,利用贪心思想:

  1. 每次选择两棵权值最小的子树,新建一个结点向两棵子树的根结点连边,合成一棵新的子树,新子树的权值为两棵子树的权值和;

  2. 不断进行 (1) 操作,如果只剩下一棵子树的时候,结束。

最终非叶子节点的权值和就等于这棵树的 sum。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值