题目1172:哈夫曼树

这是一篇关于哈夫曼树及其在数据压缩中应用的博客。文章可能详细介绍了哈夫曼树的构建过程,以及如何利用哈夫曼树进行高效的数据编码,从而达到节省存储空间的目的。读者将了解到哈夫曼编码的基本原理和实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目1172:哈夫曼树

时间限制:1 秒

内存限制:32 兆

特殊判题:

提交:4507

解决:1905

题目描述:

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

输入:

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

输出:

输出权值。

样例输入:
5  
1 2 2 5 9
样例输出:
37
来源:
2010年北京邮电大学计算机研究生机试真题

c++代码:
//1172 哈夫曼树
 
/*
哈夫曼树求法:
(1)所有结点放入集合K
(2)若集合K结点数目大于等于2个,取出权值最小的两个,构造他们同时
    为某个新节点的左右子结点,该新结点就是他们的共同双亲,设定结点权值为
    两个儿子结点的权值和。该父亲结点放入集合K。重复步骤(2)或者(3) 
(3) 若集合K结点数目只有1个,则该结点就是构造出的哈夫曼树的根结点,所有构造得到
    的非叶子结点的权值和就是哈夫曼树的最短路径和 
*/
//使用优先队列定义小顶堆
  
#include<stdio.h>
#include<queue>
 
using namespace std;
 
int
main(void)
{
    priority_queue<int, vector<int>, greater<int> >pq;//自增优先队列的定义 
    int ans;//权值之和
      
    int n;
    while(~scanf("%d",&n))
    {
        ans = 0; 
        //清空
        while(!pq.empty())
            pq.pop();
              
        int i,tmp;
        for(i=0; i<n; ++i)//入堆 
        {
            scanf("%d",&tmp);
            pq.push(tmp);
        }
         
        while(pq.size() > 1)
        {
            int pre,pro;//取两个数 
            pre = pq.top();
            pq.pop();
            pro = pq.top();
            pq.pop();
             
            ans += pre + pro;
             
            pq.push(pre+pro);//两个结点的父结点入堆 
        }
         
        printf("%d\n",ans); 
    }
    return 0;
} 
/**************************************************************
    Problem: 1172
    User: ranchothu
    Language: C++
    Result: Accepted
    Time:10 ms
    Memory:1024 kb
****************************************************************/