【考研每日一题25】哈夫曼树(C++)

原题地址:牛客网

题目描述:

哈夫曼树,第一行输入一个数n,表示叶结点的个数。需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和。

输入描述:

输入有多组数据。
每组第一行输入一个数n,接着输入n个叶节点(叶节点权值不超过100,2<=n<=1000)。

输出描述:

输出权值。

示例1

输入

5  
1 2 2 5 9

输出

37

分析:

一道哈夫曼树签到题。

代码:

#include<iostream>
#include<vector>
#include<cmath>
#include<queue>
using namespace std;
int main()
{
    int n;
    while(cin>>n)
    {
        int a;
        priority_queue<int,vector<int>,greater<int> >p;
        for(int i=0;i<n;i++)
        {
            cin>>a;
            p.push(a);
        }
        int m1,m2;
        int sum=0;
        while(p.size()>1)
        {
            m1=p.top();
            p.pop();
            m2=p.top();
            p.pop();
            sum=sum+m1+m2;
            p.push(m1+m2);
        }
        cout<<sum<<endl;
    }
    return 0;
}

2020.4.13

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是一种带权路径长度最短的二叉,通常用于数据压缩。构造哈的过程可以分为以下几步: 1. 创建一个权值数组,用于存储每个字符在文本中出现的频率或权重。 2. 创建一个森林,森林中的每个节点都是一个单独的字符,并以该字符出现的频率作为节点的权重。 3. 每次从森林中选出两个权值最小的节点作为左右子节点,将它们合并成一个新节点,并以这两个节点的权重之和作为新节点的权重。 4. 将新节点插入到森林中,并从森林中删除原来的两个节点。 5. 重复第3步和第4步,直到森林中只剩下一个根节点,即为哈的根节点。 下面是一个基本的C++实现: ```cpp struct Node { char ch; // 节点存储的字符 int weight; // 节点的权重 Node *left, *right; // 左右子节点 Node(char c, int w): ch(c), weight(w), left(NULL), right(NULL) {} }; // 构造哈 Node* buildHuffmanTree(int weights[], int n) { // 定义一个优先队列用于存储所有节点 priority_queue<Node*, vector<Node*>, [](const Node* a, const Node* b) { return a->weight > b->weight; }> pq; // 将每个字符作为单独的节点插入到队列中 for (int i = 0; i < n; i++) { if (weights[i] > 0) { pq.push(new Node((char)i, weights[i])); } } // 逐步合并节点,构造哈 while (pq.size() > 1) { Node* left = pq.top(); pq.pop(); Node* right = pq.top(); pq.pop(); Node* parent = new Node('\0', left->weight + right->weight); parent->left = left; parent->right = right; pq.push(parent); } return pq.top(); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值