【哈夫曼树】哈夫曼树求带权路径和

·大致思路:

首先要了解哈夫曼树的一些概念:

①带权路径:每个叶子结点都有权值,对于某叶子结点来说,它的带权路径就是“结点权值*从根节点到该结点的路径长度”。

②哈夫曼树的构造方法:两个权值最小的叶子结点作为兄弟去构成一个非叶节点。(该父亲非叶节点的权值=二者之和)

之前我只知道这些基本概念,求带权路径和的时候也只是“数数”——数路径长度,乘上叶子结点权值。但是,其实求带权路径和还有更简单实用的方法!

对于这个哈夫曼树,可以知道,由于非叶节点之间是具有“包含”关系的,比如29=15+14=7+8+14,58=7+8+14+29,会发现,越往高走,越会重复累加一次下面的叶子结点,其实这就隐含体现了“路径长度”。

得出结论:哈夫曼树的带权路径和=非叶节点的权值之和

 

同时,要记住的是:如何以O(nlogn)的时间复杂度实现哈夫曼树

方法:优先队列模拟“小顶堆”,每次取出堆顶的两个最小的叶子结点组成一个非叶节点,sum+=非叶节点的权值。

优先队列默认是“大顶堆”,也就是top是最大的,而我们要用小顶堆,一直在递增~一直在greater~所以要写成:priority_queue<int, vector<int>, greater<int> >

 

·AC代码:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#include<queue>
priority_queue<int, vector<int>, greater<int> > q; //小顶堆实现哈夫曼树!记住写法
int n;

int main()
{
    int x;
    int sum=0;
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0;i<n;i++)
        {
            cin>>x;
            q.push(x);
        }
        while(q.size()>1)
        {
            //找到两个最小的
            int a=q.top();
            q.pop();
            int b=q.top();
            q.pop();
            q.push(a+b);
            sum+=(a+b);
        }
        cout<<sum<<endl;
        q.pop(); //清空根节点,准备迎接下一组数据
        sum=0; //清空sum,准备迎接下一组数据
    }
    
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值