当前位置: 首页 > news >正文

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提供了以下基本操作:

  1. push():向优先级队列中添加一个元素。

  2. top():返回优先级队列中优先级最高的元素(即队首元素),但不会删除该元素。

  3. pop():删除优先级队列中优先级最高的元素(即队首元素)。

  4. size():返回优先级队列中的元素数量。

  5. empty():检查优先级队列是否为空。

  6. 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标准库中&#xff0c;优先级队列是一种非常有用的数据结构&#xff0c;它允许我们根据元素的优先级来对其进行排序和访问。这种数据结构在多种应用场景中都发挥着重…...

浅谈Acrel-2000ES储能能量管理系统的设计与应用-安科瑞 蒋静

0 前言 为进一步提升河南省分布式光伏发电发展水平&#xff0c;促进行业健康可持续发展&#xff0c;河南省发布关于促进分布式光伏发电健康可持续发展的通知。对于储能行业&#xff0c;可以用到安科瑞Acrel-2000ES储能能量管理系统。 储能柜EMS能量管理系统 1、产品名称 储…...

会员卡积分小程序系统源码商业运营版 行业一站式解决方案附带源代码以及搭建安装部署教程

系统概述 会员卡积分小程序系统源码商业运营版是一套完整的会员卡积分系统解决方案&#xff0c;包含前端小程序、后端管理系统以及数据库设计。该系统支持多种会员卡类型、积分规则设定、积分兑换、优惠券发放等功能&#xff0c;满足企业对于会员积分管理的各种需求。同时&…...

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是什么&#xff1f; Mac安装Yarn 使用Homebrew安装Yarn 使用npm安装Yarn Windows安装Yarn 使用npm安装Yarn Yarn使用 常用命令&#xff1a; 特殊命令&#xff1a; Yarn是什么&#xff1f; Yarn是一个流行的包管理工具&#xff0c;用于管理JavaScript项目的依…...

高考志愿系统-学生管理模块分析

1.获取学生信息&#xff1a; 接口&#xff1a;http://localhost:81/dev-api/college_entrance/student/list?pageNum1&pageSize10 请求方式get 默认传参pageNum和pageSize&#xff0c;表示当前页&#xff0c;每页展示数量 首先通过startPage()方法获取分页参数当前页&…...

【问题实操】银河高级服务器操作系统实例分享,开机之后反复重启

1.服务器环境以及配置 物理机/虚拟机/云/容器 物理机 外网/私有网络/无网络 私有网络 处理器&#xff1a; PHYTIUM FT2000PLUS 2200 MHz 内存&#xff1a; 128 GiB 整机类型/架构&#xff1a; HIKVISION DS-V BIOS版本&#xff1a; HK 601FBE02HK 网卡&#xff1…...

攻防世界-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学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文档可参考专栏&#xff1a;通信网络技术_Once-Day的…...

16-LINUX--线程安全

一。线程安全 线程安全即就是在多线程运行的时候&#xff0c;不论线程的调度顺序怎样&#xff0c;最终的结果都是 一样的、正确的。那么就说这些线程是安全的。 要保证线程安全需要做到&#xff1a; 1&#xff09; 对线程同步&#xff0c;保证同一时刻只有一个线程访问临界资…...

Flask SQLAlchemy 技术指南

文章目录 什么是 Flask SQLAlchemy&#xff1f;安装 Flask SQLAlchemy创建 Flask 应用和数据库模型添加和查询数据运行 Flask 应用总结**数据库迁移&#xff08;Database Migrations&#xff09;****复杂查询****关系模型****事务处理****性能优化****安全性****扩展功能** Fla…...

js通过时间对JSON中的数据进行排序

需求 现在需要通过每一个数据段的date字段对数组的整体数据进行排序&#xff01; 元数据如下&#xff1a; var data [{"filename": "123","date": "2024-05-10 19:53:57","stand": "GB-14","filter":…...

leetcode206-Reverse Linked List

题目 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 分析 用一个指针记录当前位置&#xff0c;另外一个指针记录当前位置的前一个位置&#xff0c…...

云计算第十二课

安装虚拟机 第一步新建虚拟机 选择自定义安装 下一步 选择稍后安装操作系统 选择系统类型和版本 选择虚拟机文件路径&#xff08;建议每台虚拟机单独存放并且路径不要有中文&#xff09;点击下一步 选择bios下一步 选择虚拟机处理器内核数量 默认硬盘或者自行调大硬盘 选择虚…...

【elasticsearch】慢查询替代查询审计的尝试

【elasticsearch】慢查询替代查询审计的尝试 使用了es有两年了&#xff0c;突然发现一个&#xff0c;es没有查询审计日志&#xff0c;某个用户查询了某个索引的审计。 找了官方文档和社区的回复都是说使用slow log替代慢查询。 尝试一下。 参考链接1&#xff1a;https://discus…...

腐烂的橘子BFS

题目&#xff1a; 腐烂的橘子 在给定的 m x n 网格 grid 中&#xff0c;每个单元格可以有以下三个值之一&#xff1a; 值 0 代表空单元格&#xff1b; 值 1 代表新鲜橘子&#xff1b; 值 2 代表腐烂的橘子。 每分钟&#xff0c;腐烂的橘子 周围 4 个方向上相邻 的新鲜橘子…...

什么是分库分表

读写分离主要应对的是数据库读并发&#xff0c;没有解决数据库存储问题。试想一下&#xff1a;如果 MySQL 一张表的数据量过大怎么办? 答案当然是分库分表 什么是分库&#xff1f; 分库 就是将数据库中的数据分散到不同的数据库上&#xff0c;可以垂直分库&#xff0c;也可…...

pytest并发执行用例方案

背景 开始做新项目的UI自动化&#xff0c;需要考虑用例的并发执行&#xff0c;因为之前做的项目是通过插件pytest-parallel 0.1.1 pytest-multithreading-allure 1.0.8来实现的&#xff0c;所以这次也打算用此方法&#xff0c;然而在实际使用过程中发现一些问题。 问题一 通…...

VO,PO,DTO

DTO&#xff08;Data Transfer Object&#xff09;数据传输对象 前后端之间的传输时使用 比如前端登录请求的请求参数有username&#xff0c;password&#xff0c;但后端pojo类user有username&#xff0c;password&#xff0c;birthday&#xff0c;gender时&#xff0c;可以创…...

Java设计模式-工厂

Java设计模式中&#xff0c;工厂模式主要包括普通工厂模式以及抽象工厂模式&#xff0c;普通工厂模式是用于制造输出不同类型的对象&#xff0c;抽象工厂模式是用于制造输出不同类型的普通工厂&#xff0c;本文主要描述工厂模式的基本用法。 如上所示&#xff0c;使用普通工厂模…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

ESP32读取DHT11温湿度数据

芯片&#xff1a;ESP32 环境&#xff1a;Arduino 一、安装DHT11传感器库 红框的库&#xff0c;别安装错了 二、代码 注意&#xff0c;DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

解读《网络安全法》最新修订,把握网络安全新趋势

《网络安全法》自2017年施行以来&#xff0c;在维护网络空间安全方面发挥了重要作用。但随着网络环境的日益复杂&#xff0c;网络攻击、数据泄露等事件频发&#xff0c;现行法律已难以完全适应新的风险挑战。 2025年3月28日&#xff0c;国家网信办会同相关部门起草了《网络安全…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...