首页 > 其他分享 >priority_queue自定义排序

priority_queue自定义排序

时间:2024-09-02 10:15:47浏览次数:8  
标签:Node queue 自定义 int priority pair include

priority_queue自定义排序

原文章地址,本文章仅作为学习记录

https://www.cnblogs.com/shona/p/12163381.html

priority_queue本质是一个堆。

  1. 头文件是#include<queue>
  2. 关于priority_queue中元素的比较

  模板申明带3个参数:priority_queue<Type, Container, Functional>,其中Type 为数据类型,Container为保存数据的容器,Functional 为元素比较方式。

  Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector。

2.1 比较方式默认用operator<,所以如果把后面2个参数缺省的话,优先队列就是大顶堆(降序),队头元素最大。特别注意pair的比较函数

  以下代码返回一个降序输出:

 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 int main(){
 5     priority_queue<int> q;
 6     for( int i= 0; i< 10; ++i ) q.push(i);
 7     while( !q.empty() ){
 8         cout<<q.top()<<endl;
 9         q.pop();
10     }
11     return 0;
12 }

以下代代码返回pair的比较结果,先按照pair的first元素降序,first元素相等时,再按照second元素降序:

 1 #include<iostream>
 2 #include<vector>
 3 #include<queue>
 4 using namespace std;
 5 int main(){
 6     priority_queue<pair<int,int> > coll;
 7     pair<int,int> a(3,4);
 8     pair<int,int> b(3,5);
 9     pair<int,int> c(4,3);
10     coll.push(c);
11     coll.push(b);
12     coll.push(a);
13     while(!coll.empty())
14     {
15         cout<<coll.top().first<<"\t"<<coll.top().second<<endl;
16         coll.pop();
17     }
18     return 0;
19 }

2.2 如果要用到小顶堆,则一般要把模板的3个参数都带进去。STL里面定义了一个仿函数greater<>基本类型可以用这个仿函数声明小顶堆

  以下代码返回一个升序输出:

 1 #include <iostream>
 2 #include <queue> 
 3 using namespace std;
 4 int main(){
 5     priority_queue<int, vector<int>, greater<int> > q;
 6     for( int i= 0; i< 10; ++i ) q.push(10-i);
 7     while( !q.empty() ){
 8         cout << q.top() << endl;
 9         q.pop();
10     }
11     return 0;
12 }

以下代代码返回pair的比较结果,先按照pair的first元素升序,first元素相等时,再按照second元素升序:

 1 #include<iostream>
 2 #include<vector>
 3 #include<queue>
 4 using namespace std;
 5 int main(){
 6     priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > coll;
 7     pair<int,int> a(3,4);
 8     pair<int,int> b(3,5);
 9     pair<int,int> c(4,3);
10     coll.push(c);
11     coll.push(b);
12     coll.push(a);
13     while(!coll.empty())
14     {
15         cout<<coll.top().first<<"\t"<<coll.top().second<<endl;
16         coll.pop();
17     }
18     return 0;
19 }

2.3 对于自定义类型,则必须重载operator<或者重写仿函数。

2.3.1 重载operator<的例子:返回true时,说明左边形参的优先级低于右边形参

 1 #include <iostream>
 2 #include <queue> 
 3 using namespace std;
 4 struct Node{
 5     int x, y;
 6     Node(int a=0, int b=0):
 7         x(a),y(b){}
 8 };
 9 bool operator<(Node a, Node b){//返回true时,说明a的优先级低于b
10     //x值较大的Node优先级低(x小的Node排在队前)
11     //x相等时,y大的优先级低(y小的Node排在队前)
12     if( a.x== b.x ) return a.y> b.y;
13     return a.x> b.x; 
14 }
15 int main(){
16     priority_queue<Node> q;
17     for( int i= 0; i< 10; ++i )
18     q.push( Node( rand(), rand() ) );
19     while( !q.empty() ){
20         cout << q.top().x << ' ' << q.top().y << endl;
21         q.pop();
22     }
23     return 0;
24 }

自定义类型重载operator<后,声明对象时就可以只带一个模板参数

但此时不能像基本类型这样声明priority_queue<Node,vector<Node>,greater<Node> >,原因是greater<Node>没有定义,如果想用这种方法定义则可以重载operator >

例子:返回的是小顶堆。但不怎么用,习惯是重载operator<

 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 struct Node{
 5     int x, y;
 6     Node( int a= 0, int b= 0 ):
 7         x(a), y(b) {}
 8 };
 9 bool operator>( Node a, Node b ){//返回true,a的优先级大于b
10     //x大的排在队前部;x相同时,y大的排在队前部
11     if( a.x== b.x ) return a.y> b.y;
12     return a.x> b.x; 
13 }
14 int main(){
15     priority_queue<Node,vector<Node>,greater<Node> > q;
16     for( int i= 0; i< 10; ++i )
17     q.push( Node( rand(), rand() ) );
18     while( !q.empty() ){
19         cout << q.top().x << ' ' << q.top().y << endl;
20         q.pop();
21     }
22     return 0;
23 }

2.3.2 重写仿函数的例子(返回值排序与2.3.1相同,都是小顶堆。先按x升序,x相等时,再按y升序):

 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 struct Node{
 5     int x, y;
 6     Node( int a= 0, int b= 0 ):
 7         x(a), y(b) {}
 8 };
 9 struct cmp{
10     bool operator() ( Node a, Node b ){//默认是less函数
11         //返回true时,a的优先级低于b的优先级(a排在b的后面)
12         if( a.x== b.x ) return a.y> b.y;      
13         return a.x> b.x; }
14 };
15 int main(){
16     priority_queue<Node, vector<Node>, cmp> q;
17     for( int i= 0; i< 10; ++i )
18     q.push( Node( rand(), rand() ) );
19     while( !q.empty() ){
20         cout << q.top().x << ' ' << q.top().y << endl;
21         q.pop();
22     }
23     return 0;
24 }

标签:Node,queue,自定义,int,priority,pair,include
From: https://www.cnblogs.com/Dreammoon/p/18392238

相关文章

  • MyBatis如何自定义项目中SQL日志
    说明:用过MyBatis框架的同学们都知道,打印SQL日志,可以通过在application.yml配置文件中加入下面配置来设置:mybatis:configuration:log-impl:org.apache.ibatis.logging.stdout.StdOutImpl但打印出来的SQL如下,丑陋不堪,不够优雅本文介绍如何自定义SQL日志拦截器......
  • C#自定义控件—转换开关
    C#用户控件之转换开关如何自定义一个转换键(Toggle)?三步绘制一个精美控件:定义属性;画布重绘;添加事件;主要技能:如何自定义属性;画布重绘的一般格式;控件的事件触发过程;技能扩展转换按钮使能时添加二次确认弹框?在From窗体中应用控件时,点击事件没有触发?属性名称在......
  • Langchain框架中的Agents全解析:类型、工具与自定义实践
    文章目录前言一、什么是Agents?举个栗子......
  • 【综合小项目】—— 爬取数据、数据处理、建立模型训练、自定义数据进行测试
    文章目录一、项目内容二、各步骤的代码实现1、爬取数据2、数据处理3、建立模型训练4、自定义数据进行预测一、项目内容1、爬取数据本次项目的数据是某购物平台中某个产品的优质评价内容和差评内容采用爬虫的selenium方法进行爬取数据内容,并将爬取的内容分别存放......
  • ROS1 入门 —— 编写自定义节点Node
    引言机器人操作系统(RobotOperatingSystem,ROS)是一个开源的元操作系统,用于开发机器人的软件。它并不是一个真正的操作系统,而是一套软件框架和服务,设计用来帮助开发者构建复杂的机器人系统。ROS提供了硬件抽象、设备驱动、库、消息传递和工具包等,使得机器人软件的开发变得......
  • spring 自定义属性解析器
    自定义属性解析器org.springframework.context.support.AbstractApplicationContext#prepareBeanFactorybeanFactory.setBeanClassLoader(getClassLoader());//设置EL表达式解析器(${})beanFactory.setBeanExpressionResolver(newStandardBeanExpressionResolver(beanFactory.g......
  • c++ STL常用容器使用(vector、deque、stack、queue、list、set、map等)
    1、vector使用动态数组,也叫可变数组,容器的空间是动态增长的,当空间不足时,申请更大一块空间,让后将原数据拷贝到新空间中,并释放原空间在这里插入图片描述1.1、初始化操作intarr[]={1,3,2,5};//1、方式一(初始化)vector<int>v1;//容器尾部插入数据v1.push_back(1);v1......
  • python并发与并行(四) ———— 用queue来协调多个线程之间的工作进度
    Python程序如果要同时执行多项任务,而这些任务又分别针对同一种产品的不同环节,那么就有可能得在它们之间进行协调。比较有用的一种协调方式是把函数拼接成管道。这样的管道与生产线比较像。它可以按先后顺序划分成几个阶段,每个阶段都由相应的函数负责。程序会把未经加工的原料放在生......
  • Vue3中的自定义事件和状态提升案例
    Vue3中的自定义事件和状态提升案例在现代Web开发中,Vue.js作为一个轻量级且灵活的前端框架,越来越受到开发者的青睐。而Vue3引入的组合式API(setup语法糖)更是让状态管理和事件处理变得更加优雅。在这篇博客中,我们将探讨如何在Vue3中利用自定义事件和状态提升,实现组件间的有效......
  • python并发与并行(六) ———— 正确的重构代码,以便用Queue做并发
    在前面“python并发与并行(五.2)————不要在每次fan-out时都新建一批Thread实例”里面,大家看到,每次都手工创建一批线程并平行地执行I/O任务是有很多缺点的。这一条要介绍另一种方案,也就是用内置的queue模块里的Queue类实现多线程管道。Queue方案的总思路是:在推进游戏时,不像原来......