优先级队列priority_queue

优先级队列是一个拥有权值的queue,其内部元素按照元素的权值排列。权值较高者排在最前优先出队。其中缺省情况下系统是通过一个max-heap以堆实现完成排序特性,表现为一个以vector表现的完全二叉树

1、优先级队列介绍

这是一个queue,所以只允许在底端加入元素,并从顶端取出元素。
但是优先级队列中的元素并非依照被推入队列的顺序排列。而是自动依照元素的权值排列。权值最高者排在最前面。
缺省的情况下维护的是一个大堆,即权值以从高到低排列。

priority_queue<Type, Container, Functional>

其中Type代表数据类型,Container代表容器类型,缺省状态为vector; Functional是比较方式,默认采用的是大顶堆(less<>)。

//升序队列  小顶堆 great 小到大
priority_queue <int,vector<int>,greater<int> > pri_que;
//降序队列  大顶堆 less  大到小 默认
priority_queue <int,vector<int>,less<int> > pri_que;

2、优先级队列内置函数

q.size();//返回q里元素个数
q.empty();//返回q是否为空,空则返回1,否则返回0
q.push(k);//在q的末尾插入k
q.pop();//删掉q的第一个元素
q.top();//返回q的第一个元素

3、自定义比较函数

①仿函数(函数对象)

使用这种方式,需要显示定义优先级队列的容器类型和比较函数

#include<iostream>
#include<queue>
using namespace std;
//函数对象类
template <typename T>
class cmp
{public://重载 () 运算符bool operator()(T a, T b){return a.x < b.x;}
};
struct node {int x;int y;
};
int main()
{node a = {1,2};node b = {0,2};node c = {1,3};node d = {2,5};node e = {3,6};priority_queue<node, vector<node>, cmp<node>> pq; // 显式指定容器类型和比较函数pq.push(a);pq.push(b);pq.push(c);pq.push(d);pq.push(e);while (!pq.empty()){cout << pq.top().x << "," << pq.top().y << endl;pq.pop();}return 0;
}

结果:

②、使用自定义类型比较关系

重载比较类型的 < 符号,之后在类型直接写类型名称即可

#include<iostream>
#include<queue>
using namespace std;
struct node {int x;int y;bool operator < (node b) const { // 这里后面的const必须加return this->x < b.x;}
};
int main()
{node a = {1,2};node b = {0,2};node c = {1,3};node d = {2,5};node e = {3,6};priority_queue<node> pq; // 只写类型名称即可pq.push(a);pq.push(b);pq.push(c);pq.push(d);pq.push(e);while (!pq.empty()){cout << pq.top().x << "," << pq.top().y << endl;pq.pop();}return 0;
}

结果:

③、使用lambda表达式

使用lambda表达式需要在pq对象构造的时候,将lambda表达式作为参数传入其中,即pq(cmp)

#include<iostream>
#include<queue>
#include<functional>
using namespace std;struct node {int x;int y;
};
int main()
{auto cmp = [](node x, node y) {return x.x < y.x;};node a = {1,2};node b = {0,2};node c = {1,3};node d = {2,5};node e = {3,6};priority_queue<node, vector<node>, decltype(cmp)> pq(cmp); // 需要在pq对象创建的时候将lambda表达式作为参数传入// priority_queue<node, vector<node>, function<bool(node, node)> > pq(cmp); // 和上面的效果相同,但是用function需要包含头文件functionalpq.push(a);pq.push(b);pq.push(c);pq.push(d);pq.push(e);while (!pq.empty()){cout << pq.top().x << "," << pq.top().y << endl;pq.pop();}return 0;
}

结果:

④、函数指针

使用函数指针与使用lambda表达式类似,都是在priority_queue<.,.,Cmp>中定义Compare的类型同时在priorityQueue(cmp)的中输入具体的对象作为参数,不过 这里使用的是函数和函数的指针(地址)而不是lambda表达式对象。

#include<iostream>
#include<queue>
#include<functional>
using namespace std;struct node {int x;int y;
};
bool cmp(node x, node y)
{return x.x < y.x;
}
int main()
{node a = {1,2};node b = {0,2};node c = {1,3};node d = {2,5};node e = {3,6};bool (*funcp)(node x, node y) = cmp;priority_queue<node, vector<node>, decltype(*funcp)> pq(*funcp);pq.push(a);pq.push(b);pq.push(c);pq.push(d);pq.push(e);while (!pq.empty()){cout << pq.top().x << "," << pq.top().y << endl;pq.pop();}return 0;
}

结果:

4、优先级队列排序函数的顺序问题

对于sort和priority_queue,使用greater和less类模板是结果不同的。

主要原因是因为priority_queue的内部实现方法是堆,less对应的是大顶堆。在此排序下调用top()得到的是堆顶,也就是取值时是从大到小。push对应的底层函数是push_heap(),每次添加元素入堆时,在默认情况下添加进去的数据作为较小值入堆。

//默认都是less
sort(vec.begin(),vec.end(),less<int>());               //内置类型从小到大   升序
priority_queue <int,vector<int>,less<int> > pql;  //top出数据从大到小   降序sort(vec.begin(),vec.end(),greater<int>());          //内置类型从大到小     降序
priority_queue <int,vector<int>,greater<int> > pqg;   //top出数据从小到大   升序
方法或容器 less()的顺序 greater()的顺序 cmp函数 > cmp函数 <
priority_queue 全是反过来的 降序 大->小 升序 小->大 升序 小->大 降序 大->小
sort 升序 小->大 降序 大->小 降序 大->小 升序 小->大

除了priority_queue使用的是堆,导致全部大小比较反了过来,其他均是正常符合逻辑的操作,即判断为func(a,b)判断为true则a在前。只有priority_queue特殊,如果func(a,b)判断为true,优先级队列中b在前。

注意: 队头在最右侧

struct node{int x;int y;
}point;
bool operator<(const node &a,const node &b)
{if(a.x==b.x) return a.y > b.y;else return a.x < b.x;
}
priority_queue<node> Q;

1、sort排序里面的比较函数,将元素按照比较函数的逻辑排序
2、优先队列priority_queue里面默认使用大顶堆,也就是less<>,并不是按照比较的顺序直接进行排序。
3、如上述代码,对于a和b的排序,先对a.x和b.x进行比较,如果前者小,其优先级低,放在后面,按照降序排列;如果两者相等,再对a.y和b.y进行比较,如果前者小,此时优先级高,放在前面,按照升序排列。
4、总结,先按照x降序排列,对于x相同的,按照y升序排列,而非直接根据大小进行排列。排列的标准是优先级,而非具体的数值大小。返回true代表优先级更低。

参考资料:
1、https://blog.csdn.net/qq_29592167/article/details/82708780
2、https://zhuanlan.zhihu.com/p/344121142
3、https://blog.csdn.net/qq_41484228/article/details/123137801
4、https://blog.csdn.net/red_red_red/article/details/84559951

优先级队列priority_queue相关推荐

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

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

  2. STL学习系列七:优先级队列priority_queue容器

    1.简介 最大值优先级队列.最小值优先级队列 优先级队列适配器 STL priority_queue 用来开发一些特殊的应用,请对stl的类库,多做扩展性学习 这里给个例子: #include< ...

  3. C++ STL 学习笔记__(6)优先级队列priority_queue基本操作

    10.2.7优先级队列priority_queue v  最大值优先级队列.最小值优先级队列 v  优先级队列适配器 STL priority_queue v  用来开发一些特殊的应用,请对stl的类 ...

  4. (P85)stl(十三):容器适配器,stack,queue,优先级队列priority_queue,make_heap

    文章目录 1.容器适配器 2.stack 3.queue 4.优先级队列priority_queue 5.make_heap 6.set 1.容器适配器 利用基本容器构造的容器,称之为容器适配器 基本 ...

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

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

  6. C++ 优先级队列 priority_queue

    优先级队列(priority_queue)是一种容器适配器(container adaptor).它要求容器具有front.push_back.pop_back等操作,并且容器具有随机访问的能力,故优 ...

  7. STL之优先级队列priority_queue

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

  8. ural 1306. Sequence Median(优先级队列 priority_queue用法)

    最近做的ural的题目总是各种错,看了解题报告都是自己没学过的玩意,有点受打击,不过ural的题目质量还是挺好的,多被虐虐有益健康. 这一题要是用数组直接超内存,用优先级队列做,刚接触这个,学习一下优 ...

  9. 详解优先级队列priority_queue(应用+模拟实现)

    优先级队列的概念 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元 素 ...

最新文章

  1. 三篇ISME讨论‘1%的微生物可培养’
  2. 深度学习笔记七:循环神经网络RNN(基本理论)
  3. 订阅点评有奖,本人获奖了
  4. 将RGB格式的颜色值转换为十六进制
  5. 一段在SAP C4C里触发S4HANA outbound Delivery的ABSL代码
  6. [vue] 说说你对vue的表单修饰符.lazy的理解
  7. 【剑指offer - C++/Java】14、链表中倒数第k的节点
  8. ssm框架sql换成MySQL_搭建ssm框架,可实现登录和数据展示以及增删改查
  9. phpcms attachment.class.php路径,解决phpcms上传不了图片的方法
  10. 第4关:HDFS-JAVA接口之删除文件
  11. 万春 读《Orange’S 一个操作系统的实现》有感
  12. php开发电脑i56200u,八代酷睿处理器好不好?i5-6200U处理器/i5-8250U处理器对比评测...
  13. iOS之healthKit
  14. 微信小程序英语学习平台+后台管理系统
  15. FFmpeg 编码、解码器列表(IOS)
  16. 随着计算机科学,行测真题_随着科学技术的发展,人机交流已经成为现实_步知行测...
  17. python简单网格五子棋_python实现简单五子棋游戏
  18. 2022骨传导蓝牙耳机推荐,最好用的几款骨传导耳机
  19. python换脸开源_Python实现AI换脸功能
  20. 微信小程序动画简单入门

热门文章

  1. 软件工程测验题+作业题【第1、4-8章】
  2. 软考中级信息系统监理师怎么考
  3. 爬虫入门------从数据看奥斯卡陪跑健将到底是谁?学院派评委都热衷于哪类电影?
  4. 基于matlab的频率特性测试仪,基于MATLAB的频率特性测试仪_终稿
  5. 快递100企业版物流查询API使用流程
  6. css3 keyframes 取消动画,CSS3 @keyframes 规则
  7. AIGC:【LLM(二)】——LangChain:由LLMs驱动的应用开发框架
  8. 用matlab设计一个简单的抽奖程序
  9. 什么是次世代?一个新人从零基础成为次世代游戏建模师需要哪些阶段?
  10. Mysql之视图(无通过视图更新数据表)