浅谈C++ STL中的优先队列(priority_queue)
2019独角兽企业重金招聘Python工程师标准>>>
从我以前的博文能看出来,我是一个队列爱好者,很多并不是一定需要用队列实现的算法我也会采用队列实现,主要是由于队列和人的直觉思维的一致性导致的。
今天讲一讲优先队列(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 beginningc.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 orderc.push_back(_Val);push_heap(c.begin(), c.end(), comp);}void pop(){ // erase highest-priority elementpop_heap(c.begin(), c.end(), comp);c.pop_back();}
https://www.cnblogs.com/cielosun/p/5654595.html
转载于:https://my.oschina.net/u/4000302/blog/3020098
浅谈C++ STL中的优先队列(priority_queue)相关推荐
- C++ STL中的优先队列(priority_queue)使用
原文:https://www.cnblogs.com/cielosun/p/5654595.html 今天讲一讲优先队列(priority_queue),实际上,它的本质就是一个heap,我从STL中 ...
- mysql declare与set的区别_浅谈MySQL存储过程中declare和set定义变量的区别
在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅 ...
- 浅谈单片机程序设计中的“分层思想”!
浅谈单片机程序设计中的"分层思想",并不是什么神秘的东西,事实上很多做项目的工程师本身自己也会在用.看了不少帖子都发现没有提及这个东西,然而分层结构确是很有用的东西,参透后会有一种 ...
- 浅谈网络爬虫中广度优先算法和代码实现
前几天给大家分享了网络爬虫中深度优先算法的介绍及其代码实现过程,没来得及上车的小伙伴们可以戳这篇文章--浅谈网络爬虫中深度优先算法和简单代码实现.今天小编给大家分享网络爬虫中广度优先算法的介绍及其代码 ...
- 浅谈软件性能测试中关键指标的监控与分析(转)
浅谈软件性能测试中关键指标的监控与分析 一.软件性能测试需要监控哪些关键指标? 软件性能测试的目的主要有以下三点: Ø 评价系统当前性能,判断系统是否满足预期的性能需求. Ø 寻找软件系统可能存在 ...
- php hasmany,浅谈laravel orm 中的一对多关系 hasMany
个人对于laravel orm 中对于一对多关系的理解 文章表 article,文章自然可以评论,表 comment 记录文章的评论,文章和评论的关系就是一对多,一篇文章可以有多个评论. 在 comm ...
- mysql key_len_浅谈mysql explain中key_len的计算方法
mysql的explain命令可以分析sql的性能,其中有一项是key_len(索引的长度)的统计.本文将分析mysql explain中key_len的计算方法. 1.创建测试表及数据 CREATE ...
- 事物日志恢复 mysql_浅谈SQL Server中的事务日志(五)----日志在高可用和灾难恢复中的作用...
本篇文章是系列文章中的第五篇,是对前一个日志系列的补充篇.如果您对日志的基本概念还没有一个比较系统的了解,可以参看本系列之前的文章: 浅谈SQL Server中的事务日志(一)----事务日志的物理和 ...
- 浅谈V8引擎中的垃圾回收机制
浅谈V8引擎中的垃圾回收机制 这篇文章的所有内容均来自 朴灵的<深入浅出Node.js>及A tour of V8:Garbage Collection,后者还有中文翻译版V8 之旅: 垃 ...
最新文章
- 从 SGD 到 Adam —— 深度学习优化算法概览 各种优化器 重点
- AI Studio下C语言编程:一道简单的C语言作业题目
- polymer 绑定html元素,使用在Polymer元素内的light dom中定义的模板
- 成功解决PackagesNotFoundError: The following packages are not available from current channels: tensorflo
- Anaconda——安装与添加 Anaconda Python 免费仓库
- VTK:可视化算法之DataSetSurface
- 四年才等来的一天,务必要立志,要下决心!
- 【转】前端的BFC、IFC、GFC和FFC
- 两个表点击分页的时候怎么判断点的是哪一个表_如何对指数估值,估值表怎么用?...
- 下一代Jquery模板-----JsRender
- 【火炉炼AI】深度学习008-Keras解决多分类问题
- nginx rewrite重写规则配置详解
- LINUX Telepresence编译详细过程记录
- 如何搭建运营级的网络直播平台
- 中国人大计算机保研生源学校,中国人民大学2021届保研、拟录取总结
- 电脑文件丢失了怎么恢复?2021最新教程汇总
- 汇总-13台虚拟机搭建一个高可用负载均衡集群架构
- canvas太极八卦图
- 计算机精品免费视频下载 收藏
- python写几个好玩的程序_怎么用python编写好玩的程序