原文:https://www.cnblogs.com/cielosun/p/5654595.html

今天讲一讲优先队列(priority_queue),实际上,它的本质就是一个heap,我从STL中扒出了它的实现代码,大家可以参考一下。

首先函数在头文件<queue>中,归属于命名空间std,使用的时候需要注意。

队列有两种常用的声明方式:

std::priority_queue<T> pq;
std::priority_queue<T, std::vector<T>, cmp> pq;

第一种实现方式较为常用,接下来我给出STL中的对应声明,再加以解释。

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

大家可以看到,默认模板有三个参数,第一个是优先队列处理的类,第二个参数比较有特点,是容纳优先队列的容器。实际上,优先队列是由这个容器+C语言中关于heap的相关操作实现的。这个容器默认是vector,也可以是dequeue,虽然后者功能更强大,而性能相对于vector较差,考虑到包装在优先队列后,后者功能并不能很好发挥,所以一般选择vector来做这个容器。第三个参数比较重要,支持一个比较结构,默认是less,默认情况下,会选择第一个参数决定的类的<运算符来做这个比较函数。

接下来开始坑爹了,虽然用的是less结构,然而,队列的出队顺序却是greater的先出!就是说,这里这个参数其实很傲娇,表示的意思是如果!cmp,则先出列,不管这样实现的目的是啥,大家只能接受这个实现。实际上,这里的第三个参数可以更换成greater,像下面这样:

std::priority_queue<T, std::vector<T>, greater<T>> pq;

一般大家如果是自定义类就干脆重载<号时注意下方向了,没人在这里麻烦,这个选择基本上是在使用int类还想小值先出列时。

从上面的剖析我们也就知道了,想要让自定义类能够使用优先队列,我们要重载小于号

class Student
{int id;char name[20];bool gender;bool operator < (Student &a) const{return id > a.id;}
};

就拿这个例子说,我们想让id小的先出列,怎么办,就要很违和的给这个小于符号重载成实际上是大于的定义。

如果我们不使用自定义类,又要用非默认方法去排序怎么办?就比如说在Dijkstra中,我们当然不会用点的序号去排列,无论是正序还是反序,我们想用点到起点的距离这个值来进行排序,我们怎样做呢?细心的读者在阅读我的有关Dijkstra那篇文章时应该就发现了做法——自定义比较结构。优先队列默认使用的是小于结构,而上文的做法是为我们的自定义类去定义新的小于结构来符合优先队列,我们当然也可以自定义比较结构。自定义方法以及使用如下,我直接用Dijkstra那篇的代码来说明:

int cost[MAX_V][MAX_V];
int d[MAX_V], V, s;
//自定义优先队列less比较函数
struct cmp
{bool operator()(int &a, int &b) const{//因为优先出列判定为!cmp,所以反向定义实现最小值优先return d[a] > d[b];}
};
void Dijkstra()
{std::priority_queue<int, std::vector<int>, cmp> pq;pq.push(s);d[s] = 0;while (!pq.empty()){int tmp = pq.top();pq.pop();for (int i = 0;i < V;++i){if (d[i] > d[tmp] + cost[tmp][i]){d[i] = d[tmp] + cost[tmp][i];pq.push(i);}}}
}

优先队列的日常使用,了解上面那些就已经足够。下面给出优先队列的所有成员函数的STL实现方法,希望你看完没有一脸卧槽的感觉。c就是你声明时候的那个vector或者其他容器。

    void push(value_type&& _Val){    // insert element at beginning
        c.push_back(_STD move(_Val));push_heap(c.begin(), c.end(), comp);}template<class... _Valty>void emplace(_Valty&&... _Val){    // insert element at beginningc.emplace_back(_STD forward<_Valty>(_Val)...);push_heap(c.begin(), c.end(), comp);}bool empty() const{    // test if queue is emptyreturn (c.empty());}size_type size() const{    // return length of queuereturn (c.size());}const_reference top() const{    // return highest-priority elementreturn (c.front());}void push(const value_type& _Val){    // insert value in priority order
        c.push_back(_Val);push_heap(c.begin(), c.end(), comp);}void pop(){    // erase highest-priority element
        pop_heap(c.begin(), c.end(), comp);c.pop_back();}

C++ STL中的优先队列(priority_queue)使用相关推荐

  1. 浅谈C++ STL中的优先队列(priority_queue)

    2019独角兽企业重金招聘Python工程师标准>>> 从我以前的博文能看出来,我是一个队列爱好者,很多并不是一定需要用队列实现的算法我也会采用队列实现,主要是由于队列和人的直觉思维 ...

  2. C++ STL实现的优先队列( priority_queue )

    本文参考的源码版本:gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project). priority_queue 本质是容 ...

  3. stl中Priority Queues(优先队列)的基本用法

    博客搬家啦 blog.ma6174.com stl中Priority Queues(优先队列)的基本用法 C++优先队列类似队列, 但是在这个数据结构中的元素按照一定的断言排列有序. C++ Prio ...

  4. STL库中的优先队列

    priority_queue是一个优先队列,优先级高的最先出队,默认最大值优先.内部实现为堆,因此出队和入队的时间复杂度均为O(logn).可以自定义优先级控制出队顺序优先队列不支持删除堆中指定元素, ...

  5. STL中的栈结构和队列结构

    队列和栈都是线性结构,但他们都是受限的线性表,即他们的操作是线性表操作的子集,利用线性表作为栈和队列类的基类会大大减轻编程工作量,提高代码的重用性 栈结构--------头文件为<stack&g ...

  6. 理解stl中的erase

    vector<Path *> vec; vec.push_back(new Path); vec.erase(vec.begin()); vector<Path > vec; ...

  7. stl中各种容器的自定义比较函数

    class elem { public:elem();elem(int aa):a(aa){} public:int a;int getA(){return a;} };class elem1 { p ...

  8. STL之优先级队列priority_queue

    摘要: priority_queue,自适应容器(即容器适配器):不能由list来组建: 最大值优先级队列(最大值始终在对首,push进去时候) 最小值优先级队列: 优先级队列适配器 STL  pri ...

  9. 优先队列priority_queue 用法详解

    优先队列priority_queue 用法详解 优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序 每次的push和pop操作,队列都会动态的调整,以达 ...

最新文章

  1. 美国数学月刊问题18-10-31
  2. ITK:灰度图像中的聚类像素
  3. Linux 下编译并运行C++程序
  4. JDK JRE 的作用与区别【转】
  5. C++ 泛型编程 实现红黑树RBTree
  6. HDU 1000 A + B Problem
  7. F - 你这是第一次让我看到落泪了呢 POJ - 3661Running 区间DP
  8. 前端开发如何做好本地接口模拟
  9. 机器视觉用c还是python_机器视觉_opencv-python环境搭建
  10. 使用mkdir创建同级多目录
  11. composer 安装dev包_「PHP编程」如何搭建私有Composer包仓库?
  12. MySQL innoDB数据插入性能优化
  13. 2021Java春招,java求职简历模板下载
  14. OpenGL基础教程
  15. 【铨顺宏项目推荐】RFID无线射频识别技术的设计思路
  16. CFA2019notes的PDF版本,热乎乎的百度网盘分享
  17. 惩罚函数求解matlab,matlab内点惩罚函数法
  18. Android APP分享功能实现 .
  19. 【AIX】AIX中级试题
  20. 【.NET Core】 hangfire

热门文章

  1. Jprofiler注册码
  2. log_bin.index not found 启动报错解决
  3. Unity3d连接SQL Server数据库出现SocketException: 使用了与请求的协议不兼容的地址错误...
  4. 驰骋工作流程引擎案例-水质检测工作流程设计开发实现过程
  5. 如何评估互阻抗放大器(第 2 部分)
  6. Java局部变量final
  7. 最详细的JavaScript和事件解读
  8. SmartAuditor----IT访问审计解决方案
  9. python shell背景颜色改变_科学网—Python Shell Background Color - 李旭的博文
  10. php mysql两个表合并_php – 我可以将两个MySQL查询合并为一个吗?