「STL::queue」标准库适配器:priority_queue(优先队列)介绍|自定义比较运算(C++)

news2024/11/18 1:32:02

目录

概述

创建销毁

内部理解

构造析构

自定义比较

赋值重构

数据访问

内存管理

数据控制

Tips


概述

priority_queue 是一种C++标准模板库STL中定义的一种序列容器,它允许你在运行时动态地进行堆操作。

priority_queue 可以自动管理内存,这意味着你可以添加任意多的元素在其中,并且你不需要手动分配和释放内存。

其虽名为优先队列,它实际上是一个堆空间。

优先队列即是容器,也是适配器,它同时具有容器和适配器的特性:

动态大小:内存空间可以根据需要自动增长和缩小。

堆行为:优先队列默认执行大顶堆操作,即优先弹出队内最大的元素,可以通过设置来更改比较关系。

元素容器:可以存储任何类型的元素,包括基本类型、对象、指针等。

接下来,我们介绍priority_queue类型定义的成员函数。

*注意*:本文不涉及allocator空间配置器和C++23新增的range类函数。


创建销毁

内部理解

默认的优先队列的内部实际就是一个时刻进行动态堆排序的堆化数组。

关于堆排序与堆化数组:「数组」堆排序 / 大根堆优化(C++)

为了理解构造函数中less<T>产生大根堆的原因,我们了解一下优先队列的内部关系比较:

优先队列内部有一个成员Compare comp;

这是一个重载了()运算符的仿函数类,comp(参数1,参数2)就会调用comp内部的比较函数。

优先队列内部使用这个类执行父子比较,即如果comp(父,子)返回true,则父子交换。

STL内置了std::less和std::greater两种仿函数类型。

默认优先队列的Compare是一个less类型,使用less(父,子)等同于{父<子}。

例如,一个储存int的优先队列内部维护的堆化操作实际上是这样的:

//以下是less的实现
template<typename T>
class less{
public:
     bool operator () (const T& a,const T&b){
         return a<b;   
     }
}
//以下是优先队列维护大根的交换逻辑
less<int> comp;
if(comp(father,child))
   swap(father,child);
//如果父<子,那么交换父子,使大的元素成为父

STL中有序容器默认以less比较,这就是为何priority_queue使用less作为比较规则却得到大根堆的原因。 

构造析构

STL库提供了以下方式创建一个priority_queue。

T表示任意类型。

无参构造

priority_queue<T>pq();

生成一个存储T类型的priority_queue,默认以vector为底层,less比较。

拷贝构造

priority_queue<T>que(const priority_queue& another);

将another整体赋值给新priority_queue。

移动构造

priority_queue<T>que(priority_queue&& another);

窃取另一个priority_queue容器,即直接获取它维护的底层指针地址,再将它的指针置空。

指示底层容器和比较规则的构造

priority_queue<T,vector<T>,Compare<T>>pq

(const Compare& compare,const vector& vec)

priority_queue<T,list<T>,Compare<T>>pq

(const Compare& compare);

priority_queue<T,deque<T>,Compare<T>>pq

(const Compare& compare);

(多么疯狂的模版实例和参数列表)

指示优先队列以列出的三种容器作为底层,以给定的compare作为比较规则。

仅有当以vector作底层使可以使用现有vector数据传值(也可以不传)。

不推荐使用list和deque。

在模版参数中的Compare若已定义,可以在参数列表中不传值。

(更多用法如lambda表达式,详见表格后示例)

提供源数据地址的构造

priority_queue<T,vector<T>,Compare<T>>pq

(const T* begin,const T* end,const Compare& compare)

从定长数组(初末指针)或另一容器(初末迭代器)中获取数据进行构造。

在模版参数中的Compare若已定义,可以在参数列表中不传值。

需要注意的是,迭代器指向的容器需是一个提供随机访问迭代器的容器。

析构函数

~priority_queuequeue();

无须手动调用。程序自动在代码块结束时调用,清理掉priority_queuequeue。

 (用C++的都是什么模版受虐狂)

自定义比较

#include <queue>
#include <list>
#include <vector>
#include <deque>
#include <functional>
template<typename T>
struct comp {
    bool operator () (const T& a, const T& b) {
        return a <= b;
    }
};
bool fun(const int& a, const int& b) {
    return a <= b;
}
int main(){
    priority_queue<int>pq0;//默认vector,less大根堆
    priority_queue<int>pq0c(pq0);
    priority_queue<int, vector<int>, greater<int>>pq1;//vector小根堆

    priority_queue<int, list<int>, greater<int>>pq2();//list 不推荐
    priority_queue<int, deque<int>, less<int>>pq3();//deque 不推荐

    //以下仅vector可用
    int a[3] = { 1,2,3 };
    vector<int>v = { 1,2,3 };
    priority_queue<int, vector<int>, greater<int>>pq4(greater<int>(), v);
            //↑提供数据源vector容器,在这种情况下,由于参数列表的设计,需要传入一个无名比较函数
    priority_queue<int, vector<int>, greater<int>>pq5(a,a+3);//提供源数据指针
    priority_queue<int, vector<int>, greater<int>>pq6(v.begin(),v.end());//提供源数据vector迭代器

    //以下是自定义比较方法
    priority_queue<int, vector<int>, comp<int>>pq7();//以类形式使用自定义比较规则(strcut和class都是可以的)
    priority_queue<int, vector<int>, decltype(&fun)>pq7(fun);//以函数形式使用自定义比较规则,decltype自推断
    auto lambda = [](const int& a, const int& b) {return a <= b; };
    priority_queue<int, vector<int>, decltype(lambda)>pq7(lambda);//以lambda表达式使用自定义比较规则,decltype自推断
    priority_queue<int, vector<int>, function<bool(const int&, const int&)>>pq7(lambda);//以lambda表达式使用自定义比较规则,显式声明
}


赋值重构

在必要时我们会对priority_queue进行重新初始化。

重载拷贝赋值=

priority_queue& (const priority_queue& another);

作用同拷贝构造。不仅可以在初始构造时使用。返回自身。

重载移动赋值=

priority_queue& (priority_queue&& another);

作用同移动构造。不仅可以在初始构造时使用。返回自身。


数据访问

访问堆顶元素

front();

返回堆顶元素。即按比较关系取得的最值元素。默认是最大元素。


内存管理

priority_queue仅有两个内存相关函数。

获取实际长度

size();

返回queue中的元素个数。

判断是否为空

empty();

size==0时返回true,否则返回false。


数据控制

priority_queue按堆执行操作。

压入

push(T elem);

压入元素。

堆顶弹出

pop_back();

弹出堆顶元素。即按比较关系取得的最值元素。默认是最大元素。

交换

(C++11)

swap(priority_queue& another);

交换两个容器的元素。

安置(C++11)

emplace(T elem);

C++11后可用,原地构造一个元素,作用与push()相同,但没有赋值过程而是原地生成新元素,所以效率更高。


Tips

通常不会使用list和deque作为优先队列的底层,这是由于他们的性能会远远差于vector底层。

vector能够以线性表的结构映射一颗完全二叉树从而实现堆,因此vector的时间和空间性能都是极好的。

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

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

相关文章

使用阿里云试用资源快速部署web应用-dofaker为例

本文介绍使用阿里云的试用资源部署dofaker的方法&#xff0c;本教程主要作学习在阿里云部署web应用之用&#xff0c;部署好应用之后&#xff0c;可以在任何地点通过公网ip访问web应用。 一、创建云主机 登录阿里云账户之后&#xff0c;点击控制台&#xff1a; 点击云服务器EC…

基于SSM的大学生心理素质测评及咨询平台系统设计与实现(源码+定制+讲解)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

vscode中配置python虚拟环境

python虚拟环境作用 Python虚拟环境允许你为每个独立的项目创建一个隔离的环境&#xff0c;这样每个项目都可以拥有自己的一套Python安装包和依赖&#xff0c;不会互相影响。实际使用中&#xff0c;可以在vscode或pycharm中使用虚拟环境。 1.创建虚拟环境的方法&#xff1a; …

天呐!关于PyCharm你竟然一无所知?

PyCharm 是一种专为 Python 开发而设计的集成开发环境&#xff08;IDE&#xff09;&#xff0c;由 JetBrains 开发。 以下是 PyCharm 的一些主要特点和常见的使用方法&#xff1a; 特点&#xff1a; 智能代码编辑&#xff1a;具有智能代码补全、语法检查、代码重构等功能&…

HISTCITE分析进阶

不可否认histcite是一个很好的文献分析的工具,他能很好的找到最重要的那几篇文章,同时也能找到研究的发文趋势、研究机构和著名的研究学者等。但是它是一个很老的软件,因而很多东西都没能跟上下载的分析。我在使用过程中,尝试做一些改变使其更好用,同时也做一些记录。 1.…

ROS学习笔记(三):VSCode集成开发环境快速安装,以及常用扩展插件配置

文章目录 前言VSCode集成开发环境1 安装VSCode2 VSCode扩展插件2.1 VSCode扩展插件模块介绍2.1 常用扩展插件配置一、语言支持类插件二、智能辅助类插件三、科学计算与数据分析类插件四、ROS开发相关插件 3 总结相关链接 前言 关于Ubuntu与ROS的常规安装&#xff0c;可以看这几…

数字经济与新质生产力:地理信息与遥感视角下的深度分析

在数字化浪潮的推动下&#xff0c;我们正见证着生产力的一次历史性飞跃。数字经济如何重塑生产力的三大要素&#xff1a;劳动对象、劳动资料和劳动者&#xff1f;让我们来深度分析数字经济如何推动新质生产力的发展。 一、数字经济与地理信息的融合 地理信息与遥感技术是数字…

如何在 Windows 10 上恢复未保存/删除的 Word 文档

您是否整夜都在处理重要的 word 文件&#xff0c;但忘记保存它&#xff1f;这篇文章是给你的。在这里&#xff0c;我们将解释如何恢复未保存的 word 文档。除此之外&#xff0c;您还将学习如何恢复已删除的 word 文档。 从专业人士到高中生&#xff0c;每个人都了解丢失重要 W…

【Android 14源码分析】WMS-窗口显示-流程概览与应用端流程分析

忽然有一天&#xff0c;我想要做一件事&#xff1a;去代码中去验证那些曾经被“灌输”的理论。                                                                                  – 服装…

资源《Arduino 扩展板1-LED灯》说明。

资源链接&#xff1a;Arduino 扩展板1-LED灯 1.文件明细&#xff1a; 2.文件内容说明 包含&#xff1a;AD工程、原理图、PCB。 3.内容展示 4.简述 该文件为PCB工程&#xff0c;采用AD做的。 该文件打板后配合Arduino使用&#xff0c;属于Arduino的扩展板。 该文件主要有…

Pytorch实现RNN实验

一、实验要求 用 Pytorch 模块的 RNN 实现生成唐诗。要求给定一个字能够生成一首唐诗。 二、实验目的 理解循环神经网络&#xff08;RNN&#xff09;的基本原理&#xff1a;通过构建一个基于RNN的诗歌生成模型&#xff0c;学会RNN是如何处理序列数据的&#xff0c;以及如何在…

计算机毕业设计Spark+PyTorch股票预测系统 股票推荐系统 股票可视化 股票数据分析 量化交易系统 股票爬虫 股票K线图 大数据毕业设计 AI

《SparkPyTorch股票预测系统》开题报告 一、研究背景与意义 随着信息技术的飞速发展和全球金融市场的日益繁荣&#xff0c;股票投资已成为广大投资者的重要选择之一。然而&#xff0c;股票市场的复杂性和不确定性使得投资者在做出投资决策时面临巨大的挑战。传统的股票分析方…

防sql注入的网站登录系统设计与实现

课程名称 网络安全 大作业名称 防sql注入的网站登录系统设计与实现 姓名 学号 班级 大 作 业 要 求 结合mysql数据库设计一个web登录页面密码需密文存放&#xff08;可以采用hash方式&#xff0c;建议用sha1或md5加盐&#xff09;采用服务器端的验证码&#…

今天推荐一个文档管理系统 Dorisoy.Pan

Dorisoy.Pan 是一个基于 .NET 8 和 WebAPI 构建的文档管理系统&#xff0c;它集成了 Autofac、MediatR、JWT、EF Core、MySQL 8.0 和 SQL Server 等技术&#xff0c;以实现一个简单、高性能、稳定且安全的解决方案。 这个系统支持多种客户端&#xff0c;包括网站、Android、iO…

PID控制原理:看下这三个故事,你就明白了

一、PID的故事 小明接到这样一个任务&#xff1a;有一个水缸点漏水(而且漏水的速度还不一定固定不变)&#xff0c;要求水面高度维持在某个位置&#xff0c;一旦发现水面高度低于要求位置&#xff0c;就要往水缸里加水。 小明接到任务后就一直守在水缸旁边&#xff0c;时间长就觉…

Python | Leetcode Python题解之第450题删除二叉搜索树中的节点

题目&#xff1a; 题解&#xff1a; class Solution:def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:cur, curParent root, Nonewhile cur and cur.val ! key:curParent curcur cur.left if cur.val > key else cur.rightif cur i…

Linux学习笔记(四):组与权限、任务调度、磁盘管理、网络配置、进程管理

Linux学习笔记&#xff08;四&#xff09;&#xff1a;组与权限、任务调度、磁盘管理、网络配置、进程管理 1. 组与权限 1.1 文件所有者 查看文件所有者&#xff1a; 使用 ls -ahl 或 ll 命令可以查看文件的详细信息&#xff0c;其中包括文件所有者。 修改文件所有者&…

基于SSM的定制衣服系统的设计与实现(定制衣服管理平台的设计与开发、智慧服装定制系统的设计与实现、定制衣服管理系统的设计与实现(源码+定制+参考文档)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

可视化图表与源代码显示配置项及页面的动态调整功能分析

可视化图表与源代码显示配置项及页面的动态调整功能分析 文章目录 可视化图表与源代码显示配置项及页面的动态调整功能分析1.分析图表源代码2.分析源代码显示功能**完整代码参考&#xff1a;** 3.分析源代码显示及动态调整**完整代码参考&#xff1a;** 4.分析代码编辑器及运行…

第1篇:Window日志分析----应急响应之日志分析篇

0x01 Window事件日志简介 Windows系统日志是记录系统中硬件、软件和系统问题的信息&#xff0c;同时还可以监视系统中发生的事件。用户可以通过它来检查错误发生的原因&#xff0c;或者寻找受到攻击时攻击者留下的痕迹。 Windows主要有以下三类日志记录系统事件&#xff1a;应…