文章目录

  • 前言
  • 一、priority_queue的介绍和使用
    • 1、priority_queue的介绍
    • 2、priority_queue的使用
  • 二、priority_queue模拟实现

前言

在优先队列中,优先级高的元素先出队列,并非按照先进先出的要求,类似一个堆(heap)。其模板声明带有三个参数,priority_queue<Type, Container, Functional>, 其中Type为数据类型,Container为保存数据的容器,Functional为元素比较方式。Container必须是用数组实现的容器,比如 vector, deque. STL里面默认用的是vector. 比较方式默认用operator< , 所以如果把后面两个参数缺省的话,优先队列就是大顶堆,队头元素最大。

一、priority_queue的介绍和使用

1、priority_queue的介绍

优先级队列文档

  1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
  2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。
  3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
  4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:
empty() 检测容器是否为空
size() 返回容器中有效元素个数
front() 返回容器中第一个元素的引用
push_back() 在容器尾部插入元素
pop_back() 删除容器尾部元素
  1. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类实例化指定容器类,则使用vector。
  2. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap和pop_heap来自动完成此操作。

2、priority_queue的使用

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意:默认情况下priority_queue是大堆。

函数声明 接口说明
priority_queue() 构造一个空的优先级队列
empty( ) 检测优先级队列是否为空,是返回true,否则返回false
top( ) 返回优先级队列中最大(最小元素),即堆顶元素
push(x) 在优先级队列中插入元素x
pop() 删除优先级队列中最大(最小)元素,即堆顶元素

用法:

  1. 默认情况下,priority_queue是大堆。
#include <vector>
#include <queue>
#include <functional> // greater算法的头文件
void TestPriorityQueue()
{// 默认情况下,创建的是大堆,其底层按照小于号比较vector<int> v{3,2,7,6,0,4,1,9,8,5};priority_queue<int> q1;for (auto& e : v)q1.push(e);cout << q1.top() << endl;// 如果要创建小堆,将第三个模板参数换成greater比较方式priority_queue<int, vector<int>, greater<int>> q2(v.begin(), v.end());cout << q2.top() << endl;
}
  1. 如果在priority_queue中放自定义类型的数据,用户需要在自定义类型中提供> 或者< 的重载。
class Date
{public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}bool operator<(const Date& d)const{return (_year < d._year) ||(_year == d._year && _month < d._month) ||(_year == d._year && _month == d._month && _day < d._day);}bool operator>(const Date& d)const{return (_year > d._year) ||(_year == d._year && _month > d._month) ||(_year == d._year && _month == d._month && _day > d._day);}friend ostream& operator<<(ostream& _cout, const Date& d){_cout << d._year << "-" << d._month << "-" << d._day;return _cout;}
private:int _year;int _month;int _day;
};
void TestPriorityQueue()
{// 大堆,需要用户在自定义类型中提供<的重载priority_queue<Date> q1;q1.push(Date(2018, 10, 29));q1.push(Date(2018, 10, 28));q1.push(Date(2018, 10, 30));cout << q1.top() << endl;// 如果要创建小堆,需要用户提供>的重载priority_queue<Date, vector<Date>, greater<Date>> q2;q2.push(Date(2018, 10, 29));q2.push(Date(2018, 10, 28));q2.push(Date(2018, 10, 30));cout << q2.top() << endl;
}

二、priority_queue模拟实现

通过对priority_queue的底层结构就是堆,因此此处只需对对进行通用的封装即可。

priority_queue.h

namespace my_priority_queue
{//优先级队列//小于template<class T>struct less{bool operator()(const T& x, const T& y){return x < y;}};//大于template<class T>struct greater{bool operator()(const T& x, const T& y){return x > y;}};template<class T, class Container = std::vector<int>, class Compare = less<T>>class priority_queue{private://大堆 <  小堆 >void AdjustUp(int child){Compare comFunc;int parent = (child - 1) / 2;while (child > 0){//if (_con[patent] < _con[child])if (comFunc(_con[parent], _con[child])){std::swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}void AdjustDown(int parent){Compare comFunc;int child = parent * 2 + 1;//默认左孩子while (child < _con.size()){if (child + 1 < _con.size() && comFunc(_con[child], _con[child + 1])){++child;}if (comFunc(_con[parent], _con[child])){std::swap(_con[parent], _con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}public:priority_queue(const Compare& comFunc = Compare()):_comFunc(comFunc){}template <class InputIterator>priority_queue(InputIterator first, InputIterator last, const Compare& comFunc = Compare()): _comFunc(comFunc){while (first != last){_con.push_back(*first);++first;}//建堆for (int i = (_con.size() - 1 - 1) / 2; i >= 0; --i){AdjustDown(i);}}void push(const T& x){_con.push_back(x);AdjustUp(_con.size() - 1);}void pop(){assert(!_con.empty());std::swap(_con[0], _con[_con.size() - 1]);_con.pop_back();AdjustDown(0);}const T& top(){return _con[0];}bool empty(){return _con.empty();}size_t size(){return _con.size();}private:Container _con;Compare _comFunc;};
}

C++优先级队列priority_queue详解及其模拟实现相关推荐

  1. 模拟实现优先级队列超详解(C++)

  2. 6-5-3:STL之stack和queue——优先级队列-priority_queue(堆)的基本使用和模拟实现以及仿函数

    文章目录 一:优先级队列-priority_queue(堆) (1)基本使用 (2)模拟实现 二:仿函数 (1)仿函数是什么 (2)使用仿函数完成大顶堆和小顶堆的构建 一:优先级队列-priority ...

  3. BlockingQueue(阻塞队列)详解

    推荐:Java并发编程汇总 BlockingQueue(阻塞队列)详解 原文地址 BlockingQueue 一. 前言 在新增的Concurrent包中,BlockingQueue很好的解决了多线程 ...

  4. 调度算法-优先级调度算法+例题详解

    1. 优先级调度算法的类型 优先级进程调度算法,是把处理机分配给就绪队列中优先级最高的进程.这时,又可进一步把该算法分成如下两种. 非抢占式优先级调度算法. 抢占式优先级调度算法. 2. 优先级的类型 ...

  5. 【C++】优先级队列priority_queue仿函数

    这里先简单介绍一下优先级队列priority_queue:优先队列是一种容器适配器,默认的情况下,如果没有为特定的priority_queue类实例化指容器类,则使用vector (deque 也是可 ...

  6. 调度算法-多级反馈队列+例题详解

    1. 调度机制 (1) 设置多个就绪队列. 优先级从高到低,时间片从小到大. (2) 每个队列都采用FCFS算法. 当新进程进入内存后,首先将它放入第一队列的末尾,按FCFS原则等待调度.当轮到该进程 ...

  7. ucos 消息队列代码详解_用python实现 多进程队的列数据处理详解,零基础记得都收藏哦

    今天就为大家分享一篇python 多进程队列数据处理详解,具有很好的参考价值,希望对大家有所帮助.喜欢的话记得点赞转发关注不迷路哦!!! 总之了写到多进程队列数据处理问题,也就不多废话了,直接来上代码 ...

  8. B-、B树详解及模拟实现

    B-.B树详解及模拟实现 文章目录 B-.B树详解及模拟实现 一.B-树 二.B树 1.性质 2.特性解释 3.B树的插入操作 4. B树的删除操作 5.B树摸拟实现 一.B-树 B-树就是B树 二. ...

  9. python 消息队列 get是从队首还是队尾取东西_python分布式爬虫中消息队列知识点详解...

    当排队等待人数过多的时候,我们需要设置一个等待区防止秩序混乱,同时再有新来的想要排队也可以呆在这个地方.那么在python分布式爬虫中,消息队列就相当于这样的一个区域,爬虫要进入这个区域找寻自己想要的 ...

  10. python多进程队列中的队列_python 多进程队列数据处理详解

    我就废话不多说了,直接上代码吧! # -*- coding:utf8 -*- import paho.mqtt.client as mqtt from multiprocessing import P ...

最新文章

  1. 扩展LLVM:添加指令、内部函数、类型等
  2. windows下安装配置cwrsync
  3. Library not found for -lPods-Unity-iPhone 的解决方法
  4. Sublime个性化配置
  5. zb怎么做渲染图_如何在ZBrush中渲染漫画风格的插画
  6. WhatsApp被曝内部收集用户数据
  7. 开源重磅分销版微信商城源码首发
  8. linux tar命令 打包压缩
  9. 为Visual Studio创建项目模板(VSIX / C#/ 2019)
  10. HDU 5294 Tricks Device 最短路最小割 -
  11. 大健康、医疗服务、商城系统、内容管理、健康数据统计、医疗问诊、慢病管理、科室管理、问诊订单、看病、挂号预约、体检订单、疾病管理、血压、血糖、运动、睡眠、物流、体温、体重、计步、心率、医院、医生、售后
  12. 用例建模指南lt;二gt;
  13. c#处理未捕获的异常(UnhandledException)
  14. 拭目以待 英国女将谢洛克或将谱写飞镖传奇
  15. 曹云金回应公式相声_疑砸挂曹云金?阎鹤祥封箱大典开玩笑要退社,郭德纲回复亮了!...
  16. python寻峰算法_在python中快速查找峰和质心
  17. dlink 备份文件_dlink交换机如何保存数据
  18. 信息技术服务标准(ITSS)
  19. 基于Power BI Desktop的电子产品综合数据分析案例
  20. LQ0198 圆周率【程序填空】

热门文章

  1. matlab生成vcf,从VCF文件中提取样本数据
  2. 猜拳游戏 java_用java实现一个猜拳小游戏
  3. WPF应用无法使用Snoop分析的解决办法
  4. gorm的Related和Association的区别
  5. 对生成对抗网络GANs原理、实现过程、应用场景的理解(附代码),另附:深度学习大神文章列表
  6. threejs中引入draco压缩后的模型
  7. 机器人导论 学习笔记2 - 运动学(D-H模型)
  8. nginx搭建mp4、flv流媒体服务器
  9. scrapy 出现400 Bad Request 问题
  10. 【转】GB2312汉字分区及内码表