STL中的优先级队列
目录
1.引言
2.简介
3.基本操作
4.实现原理
5.自定义优先级比较
6.相关题目
7.能特点
8.总结
1.引言
在C++标准库中,优先级队列是一种非常有用的数据结构,它允许我们根据元素的优先级来对其进行排序和访问。这种数据结构在多种应用场景中都发挥着重要作用,如任务调度、路由算法、图形算法等。本文将深入探讨C++中优先级队列的实现原理、使用方法以及性能特点。
2.简介
优先级队列(Priority Queue)是一种数据结构,其中每个元素都有一个与之关联的“优先级”。在优先级队列中,元素的排列顺序是根据它们的优先级来确定的,而不是它们进入队列的顺序。通常情况下,优先级最高的元素会最先出队。
C++标准库中的priority_queue容器就是一个典型的优先级队列实现。它是一个拥有权值观念的队列,其元素的排列顺序并不是按照插入顺序,而是根据每个元素所关联的优先级(权值)来确定的。默认情况下,priority_queue使用<操作符对元素进行比较,因此优先级最高的元素将位于队列的顶部。
大堆
vector<int> v = { 27, 15, 19, 18, 28, 34, 65, 49, 25, 37 };
priority_queue<int, vector<int>, less<int>> pq(v.begin(), v.end());
//priority_queue<int, vector<int>> pq(v.begin(), v.end()); //写法一样

小堆
vector<int> v = { 27, 15, 19, 18, 28, 34, 65, 49, 25, 37 };
priority_queue<int, vector<int>, greater<int>> pq(v.begin(), v.end()); //生成小堆

3.基本操作
C++中的priority_queue提供了以下基本操作:
-
push():向优先级队列中添加一个元素。
-
top():返回优先级队列中优先级最高的元素(即队首元素),但不会删除该元素。
-
pop():删除优先级队列中优先级最高的元素(即队首元素)。
-
size():返回优先级队列中的元素数量。
-
empty():检查优先级队列是否为空。
-
emplace() : 构造并插入一个元素
下面是一个简单的示例代码,展示了如何使用priority_queue:
#include <iostream>
#include <queue>
using namespace std;int main() {// 创建一个空的优先级队列priority_queue<int> pq;// 向优先级队列中添加元素pq.push(3);pq.push(5);pq.push(1);pq.push(4);// 输出优先级队列的大小和队首元素cout << "Size of priority queue: " << pq.size() << endl;cout << "Top element: " << pq.top() << endl; // 输出5,因为5是优先级最高的元素// 删除队首元素并输出剩余元素的大小和队首元素pq.pop();cout << "Size after pop: " << pq.size() << endl;cout << "Top element after pop: " << pq.top() << endl; // 输出4,现在是优先级最高的元素return 0;
}
4.实现原理
在C++标准库中,priority_queue通常是基于堆(Heap)数据结构来实现的。堆是一种特殊的树形数据结构,它满足堆属性:即任意节点都小于或等于(在最大堆中)或大于或等于(在最小堆中)其子节点。在priority_queue中,默认情况下使用的是最大堆,因此优先级最高的元素(即值最大的元素)总是位于堆的顶部。
当向优先级队列中添加一个新元素时,该元素会被插入到堆的末尾,然后通过“上浮”(Percolate Up)操作来重新调整堆的结构,以确保其满足堆属性。同样地,当从优先级队列中删除元素时(通常是删除优先级最高的元素),堆会通过“下沉”(Percolate Down)操作来重新调整其结构。
5.自定义优先级比较
默认情况下,priority_queue使用<操作符对元素进行比较,以确定它们的优先级。然而,有时我们可能需要根据特定的比较逻辑来定义元素的优先级。为此,我们可以向priority_queue传递一个自定义的比较函数或函数对象。
下面是一个示例代码,展示了如何使用自定义的比较函数来创建一个最小堆(即优先级最低的元素位于堆顶):
#include <iostream>
#include <queue>
#include <vector>
#include <functional> // 用于std::greater<int>
using namespace std;int main() {// 使用自定义的比较函数(std::greater<int>)来创建一个最小堆priority_queue<int, vector<int>, greater<int>> min_heap;// 向最小堆中添加元素min_heap.push(3);min_heap.push(1);min_heap.push(4);min_heap.push(1); // 允许重复元素min_heap.push(5);// 输出最小堆的队首元素(即优先级最低的元素)cout << "Top element of min_heap: " << min_heap.top() << endl; // 输出1,因为1是优先级最低的元素(值最小)return 0;
}
6.相关题目
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 1:
输入:
[3,2,1,5,6,4],k = 2
输出: 5
示例 2:
输入:
[3,2,3,1,2,4,5,5,6],k = 4
输出: 4
提示:
1 <= k <= nums.length <= 105-104 <= nums[i] <= 104
题目中有要求,必须设计时间复杂度为O(N)的算法。那么先进行排序操作的同学就另寻他路吧。这道题就可以用到优先级队列,就是堆。先把堆建好,然后pop k-1次后的堆顶就是第k大的元素。
class Solution
{
public:int findKthLargest(vector<int>& nums, int k) {priority_queue<int> pq(nums.begin(), nums.end());while(--k){pq.pop();}return pq.top();}
};
7.能特点
由于priority_queue是基于堆来实现的,因此其插入和删除操作的时间复杂度都是O(log n),其中n是队列中的元素数量。这使得priority_queue在处理大量数据时仍然能够保持较高的性能。然而,需要注意的是,由于堆的结构特点,访问队列中的非队首元素需要遍历整个队列,因此其时间复杂度为O(n)。在实际应用中,我们通常只关心优先级最高的元素(即队首元素),因此这个限制通常不会成为问题。
8.总结
C++中的priority_queue是一个功能强大的数据结构,它允许我们根据元素的优先级来对其进行排序和访问。通过深入了解其实现原理和使用方法,我们可以更加有效地利用这个工具来解决实际问题。同时,通过自定义优先级比较逻辑,我们可以进一步扩展其应用范围以满足特定的需求。
相关文章:
STL中的优先级队列
目录 1.引言 2.简介 3.基本操作 4.实现原理 5.自定义优先级比较 6.相关题目 7.能特点 8.总结 1.引言 在C标准库中,优先级队列是一种非常有用的数据结构,它允许我们根据元素的优先级来对其进行排序和访问。这种数据结构在多种应用场景中都发挥着重…...
浅谈Acrel-2000ES储能能量管理系统的设计与应用-安科瑞 蒋静
0 前言 为进一步提升河南省分布式光伏发电发展水平,促进行业健康可持续发展,河南省发布关于促进分布式光伏发电健康可持续发展的通知。对于储能行业,可以用到安科瑞Acrel-2000ES储能能量管理系统。 储能柜EMS能量管理系统 1、产品名称 储…...
会员卡积分小程序系统源码商业运营版 行业一站式解决方案附带源代码以及搭建安装部署教程
系统概述 会员卡积分小程序系统源码商业运营版是一套完整的会员卡积分系统解决方案,包含前端小程序、后端管理系统以及数据库设计。该系统支持多种会员卡类型、积分规则设定、积分兑换、优惠券发放等功能,满足企业对于会员积分管理的各种需求。同时&…...
uniapp 百度地图 拖动获取经纬度级搜索连用
import loadBMap from /utils/loadBMap.js// 百度聚合具体代码 // 拖动 initMapc() {let that thisloadBMap(百度key).then(() > {map new BMap.Map(mapContainer)const centerPoint new BMap.Point(this.longitude, this.latitude)map.centerAndZoom(centerPoint, this.…...
Yarn的安装和使用详细教程(Mac/Window)
目录 Yarn是什么? Mac安装Yarn 使用Homebrew安装Yarn 使用npm安装Yarn Windows安装Yarn 使用npm安装Yarn Yarn使用 常用命令: 特殊命令: Yarn是什么? Yarn是一个流行的包管理工具,用于管理JavaScript项目的依…...
高考志愿系统-学生管理模块分析
1.获取学生信息: 接口:http://localhost:81/dev-api/college_entrance/student/list?pageNum1&pageSize10 请求方式get 默认传参pageNum和pageSize,表示当前页,每页展示数量 首先通过startPage()方法获取分页参数当前页&…...
【问题实操】银河高级服务器操作系统实例分享,开机之后反复重启
1.服务器环境以及配置 物理机/虚拟机/云/容器 物理机 外网/私有网络/无网络 私有网络 处理器: PHYTIUM FT2000PLUS 2200 MHz 内存: 128 GiB 整机类型/架构: HIKVISION DS-V BIOS版本: HK 601FBE02HK 网卡࿱…...
攻防世界-web-unseping
题目 知识点 PHP代码审计PHP序列化和反序列化PHP中魔术方法命令执行绕过方式 解读源码 <?php highlight_file(__FILE__);class ease{private $method;private $args;function __construct($method, $args) {$this->method $method;$this->args $args;}function …...
网络网络层之(4)IPv4协议
网络网络层之(1)IPv4协议 Author: Once Day Date: 2024年4月4日 一位热衷于Linux学习和开发的菜鸟,试图谱写一场冒险之旅,也许终点只是一场白日梦… 漫漫长路,有人对你微笑过嘛… 全系列文档可参考专栏:通信网络技术_Once-Day的…...
16-LINUX--线程安全
一。线程安全 线程安全即就是在多线程运行的时候,不论线程的调度顺序怎样,最终的结果都是 一样的、正确的。那么就说这些线程是安全的。 要保证线程安全需要做到: 1) 对线程同步,保证同一时刻只有一个线程访问临界资…...
Flask SQLAlchemy 技术指南
文章目录 什么是 Flask SQLAlchemy?安装 Flask SQLAlchemy创建 Flask 应用和数据库模型添加和查询数据运行 Flask 应用总结**数据库迁移(Database Migrations)****复杂查询****关系模型****事务处理****性能优化****安全性****扩展功能** Fla…...
js通过时间对JSON中的数据进行排序
需求 现在需要通过每一个数据段的date字段对数组的整体数据进行排序! 元数据如下: var data [{"filename": "123","date": "2024-05-10 19:53:57","stand": "GB-14","filter":…...
leetcode206-Reverse Linked List
题目 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1: 输入:head [1,2,3,4,5] 输出:[5,4,3,2,1] 分析 用一个指针记录当前位置,另外一个指针记录当前位置的前一个位置,…...
云计算第十二课
安装虚拟机 第一步新建虚拟机 选择自定义安装 下一步 选择稍后安装操作系统 选择系统类型和版本 选择虚拟机文件路径(建议每台虚拟机单独存放并且路径不要有中文)点击下一步 选择bios下一步 选择虚拟机处理器内核数量 默认硬盘或者自行调大硬盘 选择虚…...
【elasticsearch】慢查询替代查询审计的尝试
【elasticsearch】慢查询替代查询审计的尝试 使用了es有两年了,突然发现一个,es没有查询审计日志,某个用户查询了某个索引的审计。 找了官方文档和社区的回复都是说使用slow log替代慢查询。 尝试一下。 参考链接1:https://discus…...
腐烂的橘子BFS
题目: 腐烂的橘子 在给定的 m x n 网格 grid 中,每个单元格可以有以下三个值之一: 值 0 代表空单元格; 值 1 代表新鲜橘子; 值 2 代表腐烂的橘子。 每分钟,腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子…...
什么是分库分表
读写分离主要应对的是数据库读并发,没有解决数据库存储问题。试想一下:如果 MySQL 一张表的数据量过大怎么办? 答案当然是分库分表 什么是分库? 分库 就是将数据库中的数据分散到不同的数据库上,可以垂直分库,也可…...
pytest并发执行用例方案
背景 开始做新项目的UI自动化,需要考虑用例的并发执行,因为之前做的项目是通过插件pytest-parallel 0.1.1 pytest-multithreading-allure 1.0.8来实现的,所以这次也打算用此方法,然而在实际使用过程中发现一些问题。 问题一 通…...
VO,PO,DTO
DTO(Data Transfer Object)数据传输对象 前后端之间的传输时使用 比如前端登录请求的请求参数有username,password,但后端pojo类user有username,password,birthday,gender时,可以创…...
Java设计模式-工厂
Java设计模式中,工厂模式主要包括普通工厂模式以及抽象工厂模式,普通工厂模式是用于制造输出不同类型的对象,抽象工厂模式是用于制造输出不同类型的普通工厂,本文主要描述工厂模式的基本用法。 如上所示,使用普通工厂模…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP
编辑-虚拟网络编辑器-更改设置 选择桥接模式,然后找到相应的网卡(可以查看自己本机的网络连接) windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置,选择刚才配置的桥接模式 静态ip设置: 我用的ubuntu24桌…...
AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
