C++ priority_queue使用方法详细介绍

更多关于STL文章——STL学习笔记

容器适配器

priority_queue

Class priority_queue<> 实现出一个 queue ,其中的元素依优先级被读取。它的接口和 queue 非常相近,亦即 push() 将会放入一个元素,top()/pop() 将会访问/移除下一个元素。然而这里所谓的“下一个元素”,并非第一个放入的元素,而是“优先级最高”的元素。换句话说,priority_queue 内的元素已经根据其值进行了排序。和往常一样,你可以通过 template 参数指定一个排序准则。默认的排序准则是以 operator < 形成降序排列,那么所谓“下一个元素”就是“数值最大的元素”。如果存在若干个数值最大的元素,我们无法确知究竟哪一个会入选。

class priority_queue 定义如下:

namespace std{
template <typename T, typename Container = vector<T>,typename Compare = less<typename Container::value_type>>
class priority_queue;
}

第一个 template 参数代表元素类型。带有默认值的第二个 template 参数定义 priority_queue 内部存放元素的实际容器,默认为 vector。带有默认值的第三个 template 参数定义出“用以查找下一个最高优先级元素”的排序准则,默认以 operator< 作为比较标准。

priority_queue 只是很单纯地把各项操作转化为内部容器的对应调用。你可以使用任何 sequence 容器支持 priority_queue,只要它们支持:random-access iterator(随机访问迭代器) 和 front()、push_back() 、 pop_back()等操作就行。由于 priority_queue 需要用到 STL heap 算法,所以其内部容器必须支持 random access(随机访问)

template<typename Tp, typename Sequence = vector<Tp>, 
			typename Compare  = less<typename Sequence::value_type> >
    class priority_queue
    {
    public:
      typedef typename	Sequence::value_type		value_type;
      typedef typename	Sequence::reference		 reference;
      typedef typename	Sequence::const_reference	   const_reference;
      typedef typename	Sequence::size_type		 size_type;
      typedef		Sequence			    container_type;
      typedef	       Compare				    value_compare;
    }
类型名称 定义
value_type 元素的类型
reference 用以指向元素之reference类型
const_reference 用以指向只读元素之reference类型
size_type 不带正负号的整数类型,用来表现大小
container_type 内部容器的类型

如你所见,priority_queue 实例默认有一个 vector 容器。函数对象类型 less 是一个默认的排序断言,定义在头文件 function 中,决定了容器中最大的元素会排在队列前面。fonction 中定义了 greater,用来作为模板的最后一个参数对元素排序,最小元素会排在队列前面。当然,如果指定模板的最后一个参数,就必须提供另外的两个模板类型参数。

构造:

explicit priority_queue(const Compare& x, const Sequence& s)
//底层容器是s的副本,按make_heap算法排序。
template <class InputIterator>
priority_queue (InputIterator first, InputIterator last, const Compare& comp, const Sequence& s);
//底层容器是s的副本,将元素插入到[first,last]范围内,然后按make_heap排序。
explicit priority_queue (const Compare& comp = Compare(), Sequence&& s = Sequence());
//默认
template <class InputIterator>
priority_queue (InputIterator first, InputIterator last, const Compare& comp, Container&& ctnr = Container());
//移动构造,底层容器是s,将元素插入到[first,last]范围内,然后按make_heap排序。
template <class Alloc> explicit priority_queue (const Alloc& alloc);
//使用分配器构造
template <class Alloc> priority_queue (const Compare& comp, const Alloc& alloc);
//比较规则+分配器
template <class Alloc> priority_queue (const Compare& comp, const Container& ctnr, const Alloc& alloc);
//比较规则+内部容器(复制)+分配器
template <class Alloc> priority_queue (const Compare& comp, Container&& ctnr, const Alloc& alloc);
//比较规则+内部容器(移动)+分配器
template <class Alloc> priority_queue (const priority_queue& x, const Alloc& alloc);
//x的内部容器(复制)+分配器
template <class Alloc> priority_queue (priority_queue&& x, const Alloc& alloc);
//x的内部容器(移动)+分配器

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

class mycomparison
{
    bool reverse;
public:
    mycomparison(const bool& revparam=false)
      {reverse=revparam;}
    bool operator() (const int& lhs, const int&rhs) const
    {
      if (reverse) return (lhs>rhs);
      else return (lhs<rhs);
    }
};

int main ()
{
    int myints[]= {10,60,50,20};

    priority_queue<int> first;
    priority_queue<int> second (myints,myints+4);
    priority_queue<int,vector<int>,greater<int>>
                            third (myints,myints+4);
    // using mycomparison:
    typedef priority_queue<int,vector<int>,mycomparison> mypq_type;

    mypq_type fourth;                       // less-than comparison
    mypq_type fifth (mycomparison(true));   // greater-than comparison

    return 0;
}

下面为其成员函数:

  • empty
    判断容器是否为空

bool empty() const;

  • size
    返回容器大小

size_type size() const;

  • top
    返回队列顶层元素

const_reference top() const;

  • push
    插入元素

void push (const value_type& val);
void push (value_type&& val);

  • emplace
    构造和插入元素

template <class… Args> void emplace (Args&&… args);

  • pop
    删除顶层元素

void pop();

  • swap
    交换两个容器

void swap (priority_queue& x);

图 1中显示元素的方式反映了它们被检索的顺序。
在这里插入图片描述

图片来源:c语言中文网

例子

题目来源:洛谷P1897

题目描述

细心的同事发现,小W最近喜欢乘电梯上上下下,究其原因,也许只有小W自己知道:在电梯里经常可以遇到他心中的女神PR。

电梯其实是个很暧昧的地方,只有在电梯里,小W才有勇气如此近距离接近女神,虽然觉得有点不自在,但次数多了,女神也习惯了小W的存在,甚至熟悉到仿佛不说上句话自己也都觉得不合适了。可是,他们的谈话也仅仅限于今天天气不错啊或是你吃了吗之类的,往往在对方微笑点头后就再次陷入难堪的沉默之中。 于是,小W便在陪伴女神的同时,也关注着电梯中显示的楼层数字,并且他注意到电梯每向上运行一层需要6秒钟,向下运行一层需要4秒钟,每开门一次需要5秒(如果有人到达才开门),并且每下一个人需要加1秒。

特别指出,电梯最开始在0层,并且最后必须再回到0层才算一趟任务结束。假设在开始的时候已知电梯内的每个人要去的楼层,你能计算出完成本趟任务需要的总时间吗?

这是个很简单的问题,要知道,小W已经修炼到快速心算出结果的境界,现在你来编程试试吧!

输入格式

共2行

第1行,一个正整数n,表示乘坐电梯的人数。

第2行,n个正整数,a[i]表示第i个人要去的楼层。

输出格式

仅1行,一个正整数,表示完成这趟任务需要的时间。

输入输出样例

输入 #1

4
2 4 3 2

输出 #1

59

说明/提示

对于60%的数据 0<n<10000

对于100%的数据 0<n<100000 0<a[i]<=2e7

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

int main ()
{
    int n;
    cin>>n;
    priority_queue<int,deque<int>,greater<int>> buf;
    int a;
    for(int i=0;i<n;++i){
        cin>>a;
        buf.push(a);
    }//数据进队

    ll tm(0);

    int floor(0),maxfloor(0);
    while(!buf.empty()){
        if(buf.size()==1){//如果队列大小只有1,说明该数即为最大楼层
            maxfloor = buf.top();
            tm+=maxfloor*4;
        }
        if(buf.top()>floor){
            tm+=(buf.top()-floor)*6+5+1;
            floor = buf.top();
            buf.pop();
        }
        else if(buf.top()==floor){
            tm+=1;
            buf.pop();
        }
    }
    cout<<tm<<endl;
    return 0;
}
原创文章 17 获赞 69 访问量 2万+

猜你喜欢

转载自blog.csdn.net/weixin_45826022/article/details/103297284