Sicily Huffman coding | 优先队列

1000.Huffman coding

Total: 328 Accepted: 115

Time Limit: 1sec Memory Limit:256MB
Description

In computer science and information theory, a Huffman code is an optimal prefix code algorithm.

In this exercise, please use Huffman coding to encode a given data.

You should output the number of bits, denoted as B(T), to encode the data:

B(T)=∑f(c)dT(c),

where f(c) is the frequency of character c, and dT(c) is be the depth of character c’s leaf in the tree T.

Input
The first line is the number of characters n.

The following n lines, each line gives the character c and its frequency f(c).

Output
Output a single number B(T).

Sample Input
Copy sample input to clipboard
5
0 5
1 4
2 6
3 2
4 3
Sample Output
45
Hint
0: 01
1: 00
2: 11
3: 100
4: 101
Problem Source: Exercise 2

题意:给定n个字符c和对应的出现的频率f(c),使用哈夫曼编码,得到每个字符在哈夫曼树的深度dT(c),求整颗树的B(T)=∑f(c)dT(c)
输入:第一个行为一个整数n,随后n行输出一对数据:字符c和频率f(c)
输出:B(T)=∑f(c)dT(c)

解法:使用优先队列 priority_queue。其模板函数为:

template<class _Ty, class _Container = vector<_Ty>, class _Pr = less<typename _Container::value_type> >

设构造的哈夫曼树节点的指针类型为Node,在这里需要用到的就是:priority_queue<Node, vector<Node>, NodeCmp> a;,优先级队列默认是使用vector作容器,底层数据结构为堆,而NodeCmp是我们自定义给堆排序用的。

代码:

#include <iostream>
#include <queue>  
#include <vector>  
using namespace std;

struct node 
{
    int fre;//频率
};
typedef node* Node;

struct NodeCmp  //自定义比较函数,使队列头为最小的元素
{  
    bool operator()(const Node &a, const Node &b)  
    {  
       return a->fre > b->fre;
    }  
};  

int main()
{
    int n;
    cin>>n;
    priority_queue<Node,std::vector<Node>,NodeCmp> Q;

    char c;
    while(n--)
    {
        Node new_node = new node;
        cin>>c>>new_node->fre;
        Q.push(new_node);
    }

    int ans=0;
    while(Q.size()>1)//构造树直到只剩下一个节点
    {
        //找出队列前面的两个fre最小的元素
        Node node1=new node;
        Node node2=new node;
        node1=Q.top();Q.pop();
        node2=Q.top();Q.pop();

        Node root=new node;
        root->fre=node1->fre+node2->fre;
        Q.push(root);

        ans+=root->fre;
    }
    cout<<ans<<endl;
}

而仔细观察,其实代码可以缩减成:

#include <iostream>
#include <queue>  
#include <vector>  
using namespace std;


int main()
{
    int n;
    cin>>n;
    priority_queue<int,std::vector<int>,greater<int> > Q;

    char c;
    int fre;
    while(n--)
    {
        cin>>c>>fre;
        Q.push(fre);
    }

    int ans=0;
    while(Q.size()>1)//构造树直到只剩下一个节点
    {
        //找出队列前面的两个fre最小的元素
        int fre1=Q.top();Q.pop();
        int fre2=Q.top();Q.pop();

        int root_fre=fre1+fre2;
        Q.push(root_fre);

        ans+=root_fre;
    }
    cout<<ans<<endl;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值