STL库--priority_queue

news2024/11/16 11:31:36

目录

priority_queue定义

prority_queue容器内元素的访问

priority_queue()常用函数实例解析

priority_queue内元素优先级的设置

priority_queue的常见用途

priority_queue又称为优先队列,其底层是用堆来进行实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那一个。例如在队列有如下元素,且定义好了优先级:

桃子(优先级3)
梨子(优先级4)
苹果(优先级1)

那么出队的顺序为梨子(4)、桃子(3)、苹果(1)

当然,可以在任何时候往优先队列里面加入元素,而优先队列底层的数据结构堆会随时调整结构,使得每次的队首元素都是优先级最大的。关于这里的优先级则是规定出来的。

priority_queue定义

其定义的写法和其他STL容器相同,typename可以是任意基本数据类型或容器

prioroty_queue<typename> name;

prority_queue容器内元素的访问

和队列不一样的是,优先队列没有front()函数与back()函数,而只能通过top()函数来访问队首元素,也就是优先级最高的元素。

#include<stdio.h>
#include<queue>
using namespace std;
int main(){
	priority_queue<int> q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n",q.top());
	return 0;
}

输出结果

4

priority_queue()常用函数实例解析

(1)push()

push(x)将令x入队,时间复杂度为O\left ( logN \right ),其中N为当前优先队列中的元素个数

(2)top()

top()可以获得队首元素,时间复杂度为O\left ( 1 \right )

(3)pop()

pop()令队首元素出队,时间复杂度为O\left ( logN \right ),其中N为当前优先队列中的元素个数。

#include<stdio.h>
#include<queue>
using namespace std;
int main(){
	priority_queue<int> q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n",q.top());
	q.pop();
	printf("%d\n",q.top());
	return 0;
}

输出结果

4
3

(4)empty()

empty()检测优先队列是否为空,返回true则空,返回false则非空,时间复杂度为O\left ( 1 \right )

#include<stdio.h>
#include<queue>
using namespace std;
int main(){
	priority_queue<int> q;
	if(q.empty()==true){
		printf("Empty\n");
	}
	else{
		printf("Not Empty\n");
	}
	q.push(1);
	if(q.empty()==true){
		printf("Empty\n");
	}
	else{
		printf("Not Empty\n");
	}
	return 0;
}

(5)size()

size()返回优先队列内元素的个数,时间复杂度为O\left ( 1 \right )

#include<stdio.h>
#include<queue>
using namespace std;
int main(){
	priority_queue<int> q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n",q.size());
	return 0;
}

priority_queue内元素优先级的设置

如何定义优先队列内元素的优先级是运用好优先队列的关键,下面分别介绍基本数据类型与结构体类型的优先级设置方法。

(1)基本数据类型的优先级设置

此处指的基本数据类型就是int型,double型,char型等可以直接使用的数据类型,优先队列对它们的优先级设置一般是数字大的优先级越高,因此队首元素就是优先队列内的元素最大的那个(如果char型,则是字典序最大的)。对基本数据类型来说,下面两种优先队列的定义是等价的(以int型为例)

prioroty_queue<int> q;
priority_queue<int,vector<int>,less<int> > q;

可以发现,第二种定义方式的尖括号多出了两个参数:一个是vector<int>,另一个是less<int>。其中vector<int>填写的是来承载底层数据结构堆的容器,如果第一个参数是double型或char型,则此处只需要填写vector<double>或vector<char>;而第三个参数less<int>则是对第一个参数的比较类,less<int>表示数字大的优先级越大,而greater<int>表示数字小的优先级越大

因此,如果想让优先队列总是把最小的元素放在队首,只需进行如下定义:

priority_queue<int,vector<int>,greater<int> > q;
#include<stdio.h>
#include<queue>
using namespace std;
int main(){
	priority_queue<int,vector<int>,greater<int> > q;
	q.push(3);
	q.push(4);
	q.push(1);
	printf("%d\n",q.top());
	return 0;
}

输出结果

1

事实上,即便是基本数据类型,也可以使用下面的结构体的优先级设置方法,只不过第三个参数的写法不太一样。

(2)结构体的优先级设置

可以举一个水果的例子,对水果的价格和名称建立一个结构体

struct fruit{
	string name;
	int price;
};

现在希望按水果的价格高的为优先级高,就需要重载小于号"<"。重载是指对已有的运算符进行重新定义,也就是说,可以改变小于号的功能,写法如下:

struct fruit{
	string name;
	int price;
	friend bool operator < (fruit f1,fruit f2){
		return f1.price < f2.price;
	}
};

可以看到,fruit结构体增加了一个函数,其中”friend"为友元,后面的”bool operator < (fruit f1,fruit f2)"对fruit类型的操作符“<"进行了重载(重载大于号会编译错误,因为从数学上来说只需要重载小于号,即f1>f2等价于判断f2<f1,而f1==f2等价于判断!(f1<f2)&&!(f2<f1),函数内部为"return f1.price<f2.price",因此重载后小于号还是小于号的作用。此时就可以直接定义fruit类型的优先队列,其内部就是以价格高的水果为优先级高。

priority_queue<fruit> q;

同理,如果想要以价格低的水果为优先级高,那么只需要把return中的小于号改为大于号即可。

struct fruit{
	string name;
	int price;
	friend bool operator < (fruit f1,fruit f2){
		return f1.price > f2.price;
	}
};

完整代码如下:

#include<iostream>
#include<string>
#include<queue>
using namespace std;
struct fruit{
	string name;
	int price;
	friend bool operator < (fruit f1,fruit f2){
		return f1.price > f2.price;
	}
}f1,f2,f3;
int main(){
	priority_queue<fruit> q;
	f1.name="桃子";
	f1.price=3;
	f2.name="梨子";
	f2.price=4;
	f3.name="苹果";
	f3.price=1;
	q.push(f1);
	q.push(f2);
	q.push(f3);
	cout<<q.top().name<<" "<<q.top().price<<endl;
	return 0;
}

输出结果

苹果 1

此处对小于号的重载与排序函数sort中的cmp函数有些相似,它们的参数都是两个变量,函数内部都是return了true或者false。事实上,这两者的作用确实是类似的,只不过效果看上去似乎是相反的。在排序中,如果return f1.price>f2.price,那么则是按照价格从高到低排序,但是在优先队列中却是把价格低的放在队首。原因在于,优先队列本身静默的规则就是优先级高的放在队首,因此把小于号重载为大于号的功能时只是把这个规则反向了一下。只需要记住,优先队列的这个函数与sort中的cmp函数的效果是相反的

或者也可以把结构体定义在外面,只需要把friend去掉,把小于号改成一对小括号,然后把重载的函数写在结构体外面,同时将其用struct包装起来。

struct cmp{
	bool operator () (fruit f1,fruit f2){
		return f1.price > f2.price;
	}
};

在这种情况下需要用之前讲解的第二种定义方式来定义优先队列

priority_queue<fruit,vector<fruit>,cmp> q;

完整代码如下:

#include<iostream>
#include<string>
#include<queue>
using namespace std;
struct fruit{
	string name;
	int price;
}f1,f2,f3;
struct cmp{
	bool operator () (fruit f1,fruit f2){
		return f1.price > f2.price;
	}
};
int main(){
	priority_queue<fruit,vector<fruit>,cmp> q;
	f1.name="桃子";
	f1.price=3;
	f2.name="梨子";
	f2.price=4;
	f3.name="苹果";
	f3.price=1;
	q.push(f1);
	q.push(f2);
	q.push(f3);
	cout<<q.top().name<<" "<<q.top().price<<endl;
	return 0;
}

当然即便是基本数据类型或者其他STL容器,也可以通过同样的方式来定义优先级。

最后指出,如果结构体内的数据较为庞大(例如出现了字符串或者数组),建议使用引用来提高效率,此时比较类的参数需要加上"const"和"&"

friend bool operator < (const fruit &f1,const fruit &f2){
	return f1.price > f2.price;
}
bool operator() (const fruit &f1,const fruit &f2){
	return f1.price > f2.price;
}

priority_queue的常见用途

priority_queue可以解决一些贪心问题,也可以对Dijkstra算法进行优化。

但是注意在使用tiop()函数前,必须用empty()判断优先队列是否为空。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1713984.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【软件测试】LoadRunner参数化属性设置_单个参数

目录 为什么使用参数化属性详解Select next rowSequential&#xff08;顺序&#xff09;Random&#xff08;随机&#xff09;Unique&#xff08;唯一&#xff09;Same line as XXX&#xff08;和XXX属性的取值方式一样&#xff09; Update value onEach iteration&#xff08;每…

用于脑肿瘤分割的跨模态深度特征学习| 文献速递-深度学习肿瘤自动分割

Title 题目 Cross-modality deep feature learning for brain tumor segmentation 用于脑肿瘤分割的跨模态深度特征学习 01 文献速递介绍 作为最致命的流行病&#xff0c;脑肿瘤的研究越来越受到关注。本文研究了一种基于深度学习的自动分割胶质瘤的方法&#xff0c;称为脑…

百度ERNIE系列预训练语言模型浅析(4)-总结篇

总结&#xff1a;ERNIE 3.0与ERNIE 2.0比较 &#xff08;1&#xff09;相同点&#xff1a; 采用连续学习 采用了多个语义层级的预训练任务 &#xff08;2&#xff09;不同点&#xff1a; ERNIE 3.0 Transformer-XL Encoder(自回归自编码), ERNIE 2.0 Transformer Encode…

vue3学习(二)

前言 上一篇分享了vue的基础指令&#xff0c;这篇记录下vue3的核心内容&#xff0c;也是自己的学习笔记&#xff0c;可能有些核心还不全&#xff0c;大佬请略过。 一、核心内容 分享这个之前&#xff0c;先声明下&#xff0c;我这里是用的脚手架的写法&#xff0c;分享的讲解截…

什么是数字化采购?一文解析!

在快速发展的数字经济时代&#xff0c;越来越多的企业开始想要了解什么是数字化采购&#xff1f;因为数字化采购已经成为提升效率、降低成本的关键举措。简单来说&#xff0c;采购数字化就是利用先进的数字化技术和工具&#xff0c;对传统的采购流程进行改造和优化&#xff0c;…

如何降本增效获得目标客户?AI企业使用联盟营销这个方法就对了!

AI工具市场正在迅速发展&#xff0c;现仍有不少企业陆续涌出&#xff0c;那么如何让你的工具受到目标群体的关注呢&#xff1f;这相比是AI工具营销人员一直在思考的问题。 为什么AI企业难以获客呢&#xff1f; 即使这个市场正蓬勃发展&#xff0c;也无法保证营销就能轻易成功…

MQ第②讲~保证消息可靠性

前言 上一讲我们讲了MQ实际工作中常见的应用场景&#xff0c;这一节讲一下消息的可靠性&#xff0c;如果对MQ掌握程度比较高的铁子&#xff0c;可以不用看&#xff0c;节省您宝贵的时间。 消息的大致链路 消息从投递到消费需要考虑如下几个问题 生产者的消息是否成功投递到消…

mac安装的VMware虚拟机进行桥接模式配置

1、先进行网络适配器选择&#xff0c;选择桥接模式 2、点击网络适配器 设置... 3、选择WiFi&#xff08;我使用的是WiFi&#xff0c;所以选择这个&#xff09;&#xff0c;注意看右边的信息&#xff1a;IP和子网掩码&#xff0c;后续配置虚拟机的ifcfg-ens文件会用到 4、编辑if…

HarmonyOS-9(stage模式)

配置文件 {"module": {"requestPermissions": [ //权限{"name": "ohos.permission.EXECUTE_INSIGHT_INTENT"}],"name": "entry", //模块的名称"type": "entry", //模块类型 :ability类型和…

小迪和小捷的太空之旅——海底观光篇

书接上回&#xff0c;小迪和小捷来到了美丽的海底世界~

第三方软件测试机构进行验收测试的好处分享,需多少时间和费用?

在软件开发过程中&#xff0c;软件验收测试是不可或缺的一环。那么&#xff0c;什么是软件验收测试呢?为什么建议选择第三方软件测试机构进行验收测试呢? 软件验收测试是指在软件开发完毕后&#xff0c;由测试人员基于软件需求规格说明书和软件设计文档等材料&#xff0c;对…

【深度学习】吸烟行为检测软件系统

往期文章列表&#xff1a; 【YOLO深度学习系列】图像分类、物体检测、实例分割、物体追踪、姿态估计、定向边框检测演示系统【含源码】【深度学习】YOLOV8数据标注及模型训练方法整体流程介绍及演示【深度学习】行人跌倒行为检测软件系统【深度学习】火灾检测软件系统【深度学…

AcWing 1600:完全二叉树

【题目来源】https://www.acwing.com/problem/content/1602/【题目描述】 给定一个树&#xff0c;请你判断它是否是完全二叉树。【输入格式】 第一行包含整数 N&#xff0c;表示树的结点个数。 树的结点编号为 0∼N−1。 接下来 N 行&#xff0c;每行对应一个结点&#xff0c;并…

查看和修改自己的git提交时的作者信息

首先查看自己本地配置的信息:git config --list 修改姓名和邮箱: 配置用户名 git config --global user.name "真实姓名" 配置邮箱 git config --global user.email "公司分配的企业邮箱" 示例 git config --global user.name "张三" git…

linux网络项目——基于WebServer的工业数据采集项目

一、项目目标和框图 项目目标&#xff1a;实现通过网页控制信息采集和通过网页控制灯泡和蜂鸣器的亮灭 二、项目分析 1.服务器源码分析 初始化服务器循环等待连接&#xff0c;连接后创建线程&#xff0c;调用线程函数msg_request&#xff0c;在函数中调用handler_msg函数分析…

AI大模型探索之路-实战篇10:数据预处理的艺术:构建Agent智能数据分析平台的基础

系列篇章&#x1f4a5; AI大模型探索之路-实战篇4&#xff1a;深入DB-GPT数据应用开发框架调研 AI大模型探索之路-实战篇5&#xff1a;探索Open Interpreter开放代码解释器调研 AI大模型探索之路-实战篇6&#xff1a;掌握Function Calling的详细流程 AI大模型探索之路-实战篇7…

Web开发中,就session和cookie相比,用session比用cookie的优点有哪些?

在Web项目中&#xff0c;session和cookie都是用于存储用户数据的机制&#xff0c;但它们有不同的优缺点。使用session比使用cookie有以下几个主要优点&#xff1a; 1. 安全性更高 敏感数据保护&#xff1a;Session数据存储在服务器端&#xff0c;而不是客户端。这样&#xff…

什么叫USDT(泰达币)的前世今生!

一、引言 在数字货币的世界里&#xff0c;USDT&#xff08;Tether USDT&#xff09;以其独特的稳定机制&#xff0c;成为了连接传统金融市场与加密货币市场的桥梁。本文将带您了解USDT的诞生背景、发展历程、技术特点以及未来展望。 二、USDT的诞生背景 USDT是Tether公司推出…

QT::QNetworkReply类readAll()读取不到数据的可能原因

程序中&#xff0c;当发送请求时&#xff0c;并没有加锁&#xff0c;而是在响应函数中加了锁&#xff0c;导致可能某个请求的finished信号影响到其他请求响应数据的读取 connect(reply,&QNetworkReply::finished,this,&Display::replyFinished);参考这篇文章&#xff…

5.28.1 使用卷积神经网络检测乳腺癌

深度学习技术正在彻底改变医学图像分析领域&#xff0c;因此在本研究中&#xff0c;我们提出了卷积神经网络 (CNN) 用于乳腺肿块检测&#xff0c;以最大限度地减少手动分析的开销。CNN 架构专为特征提取阶段而设计&#xff0c;并采用了更快的 R-CNN 的区域提议网络 (RPN) 和感兴…