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

Priority_queue

一、priority_queue的介绍和使用

1.1 priority_queue的介绍

1.优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。

2.优先队列类似于堆, 在堆中可以随时插入元素, 并且只能检索最大堆元素(优先队列中位于顶部的元素)。

3.优先队列被实现为容器适配器,容器适配器即将特定的容器类封装作为其底层容器,queue提供一组特定的成员函数来访问其元素,元素从特定容器的尾部弹出,这里称为优先队列的顶部。

4.底层容器可以是任何标准容器类模版,也可以是其他特定设计的容器类,容器应该可以通过随机访问和迭代器访问,需要支持一下操作:

  • empty() : 判断容器是否为空

  • size() : 返回容器中的有效元素个数

  • front() : 返回容器中的第一个元素的引用

  • push_back() : 在容器中尾插元素

  • pop_back() : 在容器中尾删元素

5.标准容器类vector和deque满足这些需求,默认情况下如果没有指定底层容器的话就默认使用vector作为优先队列的底层容器。

6.需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用算法函数make_heap、push_heap、和pop_heap来自动完成此操作。

1.2 priority_queue的使用

优先级队列默认使用vector作为求底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以使用priority_queue来替代。

注意:默认情况下,priority_queue是大堆

函数声明接口说明
priority_queue()/priority_queue(first, last)构造一个空的优先级队列
empty()检测优先级队列是否为空,是的话就返回true否则返回false
top()返回优先级队列中最大(最小)的元素,即堆顶元素(默认是大堆,返回最大元素)
push(x)在优先级队列中插入元素x
pop()删除优先级队列中最大(最小)元素,即删除堆顶元素

下面我们来看下优先队列的使用实例:

#include<iostream>
#include<vector>
#include<queue>
//greater算法的头文件
#include<functional>using namespace std;void test1()
{//默认情况下是建大堆priority_queue<int> q1;vector<int> arr{ 1, 3, 4, 5, 6 , 7, 9, };for (auto& e : arr){q1.push(e);}while (!q1.empty()){cout << q1.top() << " ";q1.pop();}cout << endl;//将第三个模版参数换成great比较方式就是建小堆priority_queue<int, vector<int>, greater<int>> q2(arr.begin(), arr.end());while (!q2.empty()){cout << q2.top() << " ";q2.pop();}cout << endl;}int main()
{test1();return 0;
}

二、OJ练习

leetcode215,数组中的第k个最大元素

题目:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们先看题意是让我们找出数组nums中的第k个最大的元素,看到样例2中我们发现相同的数也会被算进k里面,因此我们在这题上面,就可以利用我们的优先级队列,我们将优先级队列中的前k -1 个元素给pop出去,那么剩下的元素中堆顶元素就是我们的第k个最大元素。

下面是这道题的参考代码:

class Solution {
public:int findKthLargest(vector<int>& nums, int k) {priority_queue<int> q1(nums.begin(), nums.end());//将前k - 1个元素pop掉就是第k个最大元素while(--k) q1.pop();//直接返回优先级队列的堆顶元素即可return q1.top();}
};

三、 priority_queue的模拟实现

3.1 仿函数的概念

仿函数又称为函数对象:重载了operator()的类,类的对象可以向函数一样使用。

operator() 的特点:参数个数和返回值是根据需求定的很灵活。

3.2 仿函数的实现

3.2.1 判断小于的仿函数

下面是我们的判断小于的仿函数的代码:

//判断小于的仿函数
template<class T>
class myless
{
public:bool operator() (T& x, T& y){return x < y;}
};

我们定义了一个重载了operator() 的类,类里面就只有一个重载函数。我们可以通过这种方式来模拟出一个函数。

3.2.2 判断大于的仿函数

下面是我们判断大于的仿函数的代码:

//判断大于的仿函数
template<class T>
class mygreater
{
public:bool operator() (T& x, T& y){return x > y;}
};

这是我们判断大于的仿函数,和判断小于的仿函数的原理相同也是使用了一个类模版,然后再里面重载了一个operator() 函数,用来模拟函数的效果。

3.3 构造以及建堆调整操作

3.3.1 构造函数

这里的构造函数我们先实现默认的无参构造:

//无参构造
priority_queue():c(), comp()
{}

将类里面的两个成员变量给一个空值, c是底层容器,comp是用来比较的仿函数。实现建堆的调整函数后我们在来实现我们的迭代器构造函数。

3.3.2 向上调整建堆

下面是我们进行维持优先级队列的顺序的函数之一,向上调整算法:

//向上调整建堆
void Adjust_up(int child)
{int parent = (child - 1) / 2;while (child > 0){//if (c[parent] < c[child])if(comp(c[parent], c[child])){swap(c[parent], c[child]);}child = parent;parent = (child - 1) / 2;}
}

我们首先要知道用数组模拟堆,也就是优先级队列,它的子节点和父亲节点的下标之间的关系,在向上建堆操作中我们是从下往上的,我们需要知道parent和child之间的关系,它们之间的关系就是 parent = (child - 1) / 2 , 这里的比较我们可以使用仿函数来比较也可以直接实用大于和小于号比较但是建议使用仿函数,因为仿函数的通用性高, 当我们的父节点小于我们的子节点时我们就将他们交换位置,然后将父节点的位置给到子节点,然后重新计算父节点,相当于是更新子节点和父节点。

3.3.3 向下调整建堆

下面是我们的向下调整算法:

//向下调整建堆
void Adjust_down(int parent)
{int child = parent * 2 + 1;if (child + 1 < c.size() && c[child] < c[child + 1]){child++;}while (child < c.size()){//if (c[parent] < c[child])if(comp(c[parent], c[child])){swap(c[parent], c[child]);}parent = child;child = parent * 2 + 1;}
}

向下建堆的效率要比向上调整建堆的效率要高很多, 在我们的迭代器区间构造和我们的pop函数中可以使用我们的向下调整算法来维持优先队列的结构。原理和向上调整建堆基本相同,向下调整算法是传入parent的值,然后计算出child的值,child和parent的关系式是:child = parent * 2 + 1, 然后我们选出最大的左右子节点中较大的那个子节点,对parent和child进行比较,如果parent的值小于child的值的话就将它们调换位置,然后将child的下标给给parent,然后再计算child的下标,相当于更新位置。

3.3.4 使用迭代器区间进行构造

下面是我们的实例代码:

 //迭代器区间构造template <class InputIterator>priority_queue(InputIterator first, InputIterator last):c(),comp(){while (first != last){c.push_back(*first);first++;}for (int i = (c.size() - 1 - 1) / 2; i >= 0; i--){Adjust_down(i);}}

这里我们直接将这个迭代器区间中的值通过迭代器遍历逐个放进我们的底层容器中即可,然后通过我们的向下调整算法进行建堆。

3.4 priority_queue中的容量以及访问访问修改操作

3.4.1 容量相关的接口

我们容量相关的接口有size和empty,size的作用是返回有效数据的个数,empty的作用是判断队列中是否为空。

下面来看我们的size接口:

//返回有效数据个数
size_t size() const
{return c.size();
}

对于我们的size接口就直接返回我们底层容器的size接口的值即可。

再来看下我们的empty接口:

 //判断优先队列里面是否为空bool empty() const{return c.empty();}

与size接口同理empty接口也是直接返回我们的底层容器的接口即可。

3.4.2 访问和修改

关于访问和修改操作的接口有:top, push, pop

下面依次来看这些接口:

top:

 //返回队头元素T& top() {return c[0];}const T& top() const{return c[0];}

top 接口的作用是返回我们的队头元素,我们的底层容器是动态数组vector我们就直接返回数组的第一个元素即可。

push:

//入队操作
//尾插入队,执行向上调整操作
void push(const T& x)
{c.push_back(x);Adjust_up(c.size() - 1);
}

对于入队操作我们直接尾插进数组即可,尾插之后执行向上调整操作。

pop:

//出队操作
//先交换最后一个元素和第一个元素的位置
//尾删出队,执行向下调整操作
void pop()
{swap(c[0], c[size() - 1]);c.pop_back();Adjust_down(0);
}

对于我们pop接口的作用时将堆顶元素给pop出去,我们将堆顶元素和数组最后一个元素进行交换位置,然后进行尾删,最后执行向下调整操作,维持堆的结构即可。


这就是这篇文章的全部内容了,希望大家能从以上内容中对优先级队列有一定的理解。


对于入队操作我们直接尾插进数组即可,尾插之后执行向上调整操作。pop:```C++
//出队操作
//先交换最后一个元素和第一个元素的位置
//尾删出队,执行向下调整操作
void pop()
{swap(c[0], c[size() - 1]);c.pop_back();Adjust_down(0);
}

对于我们pop接口的作用时将堆顶元素给pop出去,我们将堆顶元素和数组最后一个元素进行交换位置,然后进行尾删,最后执行向下调整操作,维持堆的结构即可。


这就是这篇文章的全部内容了,希望大家能从以上内容中对优先级队列有一定的理解。

相关文章:

Priority_queue

一、priority_queue的介绍和使用 1.1 priority_queue的介绍 1.优先队列是一种容器适配器&#xff0c;根据严格的弱排序标准&#xff0c;它的第一个元素总是它所包含的元素中最大的。 2.优先队列类似于堆&#xff0c; 在堆中可以随时插入元素&#xff0c; 并且只能检索最大堆…...

SpringMVC:获取请求数据

1. 通过RequestParma注解接收 /**** value和name都可以使用&#xff0c;互为别名* 如果此处设置了需要什么参数而前端请求时没有提供则会报400&#xff08;请求参数不一致错误&#xff09;* required参数用于设置该参数是否为必须传递参数&#xff0c;默认为true必须传递* defa…...

深度学习 --- stanford cs231 编程作业(assignment1,Q2: SVM分类器)

stanford cs231 编程作业之SVM分类器 写在最前面&#xff1a; 深度学习&#xff0c;或者是广义上的任何学习&#xff0c;都是“行千里路”胜过“读万卷书”的学识。这两天光是学了斯坦福cs231n的一些基础理论&#xff0c;越往后学越觉得没什么。但听的云里雾里的地方也越来越多…...

【scikit-learn010】sklearn算法模型清单实战及经验总结(已更新)

1.一直以来想写下基于scikit-learn训练AI算法的系列文章,作为较火的机器学习框架,也是日常项目开发中常用的一款工具,最近刚好挤时间梳理、总结下这块儿的知识体系。 2.熟悉、梳理、总结下scikit-learn框架模型算法包相关技术点及经验。 3.欢迎批评指正,欢迎互三,跪谢一键…...

Rethinking overlooked aspects in vision-language models

探讨多模态视觉语言模型的一些有趣结论欢迎关注 CVHub!https://mp.weixin.qq.com/s/zouNu-g-33_7JoX3Uscxtw1.Introduction 多模态模型架构上的变化不大,数据的差距比较大,输入分辨率和输入llm的视觉token大小是比较关键的,适配器,VIT和语言模型则不是那么关键。InternVL-…...

【漯河市人才交流中心_登录安全分析报告-Ajax泄漏滑动距离导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 暴力破解密码&#xff0c;造成用户信息泄露短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造成亏损无底洞…...

C语言—字符函数和字符串函数

1.字符分类函数 C语言中有一系列的函数是专门做字符分类的&#xff0c;也就是一个字符是属于什么类型的字符的。 这些函数的使用都需要包含一个头文件 ctype.h。 例&#xff1a;将一句话中的小写字母改成大写字母。 2.字符转换函数 头文件&#xff1a;ctype.h C语言提供了2…...

爬山算法的详细介绍

爬山算法&#xff08;Hill Climbing Algorithm&#xff09;是一种基于启发式的局部搜索算法&#xff0c;常用于解决优化问题。它的核心思想是从当前解的邻域中选择能够使目标函数值最大&#xff08;或最小&#xff09;的下一个解作为当前解&#xff0c;直到找到一个满足问题要求…...

硕士课程 可穿戴设备之作业一

作业一 第一个代码使用的方法是出自于[1]。 框架结构 如下图&#xff0c;不过根据对代码的解读&#xff0c;发现作者在代码中省去了对SSR部件的实现&#xff0c;下文再说。 Troika框架由三个关键部件组成&#xff1a;信号分解&#xff0c;SSR和光谱峰值跟踪。&#xff08;粗…...

测试记录3:WLS2运行Linux界面

1.WLS1转到WLS2 &#xff08;1&#xff09;根据自己的平台&#xff0c;下载WLS2安装包 x64: https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi arm64: https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_arm64.msi &#xff08;2&…...

好用软件推荐

软件功能相关介绍地址FastStone截图&#xff08;长截图、定时截图等&#xff09;CSDNhttps://www.faststone.org/FSCaptureDownload.htmQuicker快捷访问https://getquicker.net/https://getquicker.net/...

王学岗鸿蒙开发(北向)——————(二)TS基本语法详解

1&#xff0c;Ts(TypeScript)语法相当于JAVAScript类型&#xff0c;鸿蒙arkTs是基于TS语言的,当然artTs也融合了其它的语言。 2&#xff0c;本篇文章是基于n9版本。注意,有些语法是已经不能用的。 3&#xff0c; 4&#xff0c;变量:用来存储数据,数字字母组成&#xff0c;数字不…...

【网络协议 | HTTP】HTTP总结与全梳理(一) —— HTTP协议超详细教程

&#x1f525;博客简介&#xff1a;开了几个专栏&#xff0c;针对 Linux 和 rtos 系统&#xff0c;嵌入式开发和音视频开发&#xff0c;结合多年工作经验&#xff0c;跟大家分享交流嵌入式软硬件技术、音视频技术的干货。   ✍️系列专栏&#xff1a;C/C、Linux、rtos、嵌入式…...

java基础选择题--11

1. 以下保留字( )不能出现在说明虚函数原型的语句中。A.static B.operator C.void D.const 参考答案&#xff1a;A 2. 一个类中只能定义一个析构函数。( )A.对 B.错 参考答案&#xff1a;A 解释&#xff1a; 在C中&#xff0c;一个类只能有一个析构函数。析构函数在对象生…...

欲除烦恼须无我,各有前因莫羡人

欲除烦恼须无我&#xff0c;各有前因莫羡人...

Vue的APP实现下载文件功能,并将文件保存到手机中

Vue的APP实现下载文件功能&#xff0c;并将文件保存到手机中 文字说明后台核心代码前台核心代码运行截图项目链接 文字说明 本文介绍Vue实现的APP&#xff0c;将文件下载并保存到手机中&#xff0c;为系统提供导出功能&#xff1b;同时支持导入&#xff0c;即选择本地的文件后&…...

泛微开发修炼之旅--07通过后端代码实现创建并发送待办、源码及示例

文章链接&#xff1a;泛微开发修炼之旅--07通过后端代码实现创建并发送待办、源码及示例...

轻松搭建AI应用的三个大模型技术路线

时下聊起AI&#xff0c;想必最热的就是使用AI的应用&#xff08;chatGPT&#xff0c;文心一言等&#xff09;来提升自己工作的效率&#xff0c;比如破局俱乐部&#xff0c;洋哥带领星球2万多人开启大航海&#xff0c;教人使用这一波新起的应用进行赚钱与赋能。 在我的视角来看…...

Vue01-vue的简介

一、Vue是什么&#xff1f; 一套用于构建用户界面的渐进式javaScript框架。 构建用户界面&#xff1a; 渐进式&#xff1a; 目前Vue的地位&#xff1a;生态完善&#xff0c;国内前端工程师必备技能。 二、Vue的特点 一个XXX.vue就是一个组件&#xff0c;封装的概念&#xff0c…...

leetcode455.分发饼干、376. 摆动序列、53. 最大子序和

455.分发饼干 为了满足更多的小孩&#xff0c;就不要造成饼干尺寸的浪费 大尺寸的饼干既可以满足胃口大的孩子也可以满足胃口小的孩子&#xff0c;那么就应该优先满足胃口大的 这里的局部最优就是大饼干喂给胃口大的&#xff0c;充分利用饼干尺寸喂饱一个&#xff0c;全局最…...

JVM的内存结构

JVM 内存结构 方法区: 方法区主要用于存储虚拟机加载的类信息、常量、静态变量&#xff0c;以及编译器编译后的代码等数据。 程序计数器 由于在JVM中&#xff0c;多线程是通过线程轮流切换来获得CPU执行时间的&#xff0c;因此&#xff0c;在任一具体时刻&#xff0c;一个CP…...

轻量管理内核复杂级别的项目

在嵌入式开发中&#xff0c;管理大型项目&#xff08;例如Linux内核&#xff09;往往是一个复杂的过程。常规的版本控制系统如Git在处理小型项目时非常高效&#xff0c;但面对庞大的代码库时可能会显得笨重且占用大量存储空间。本文将介绍几种轻量级的方法来管理内核级别的项目…...

【wiki知识库】05.分类管理模块--后端SpringBoot模块

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、&#x1f525;今日目标 二、☀SpringBoot代码修改 1.使用逆向工程生成Category表结构 2. 新增CategoryQueryParam 3.新增CategorySaveParam 4.新增CategotyQueryVo 三、&#x1f916;新增分类管理的相关接口…...

资源目录与云SSO

1、开启资源目录 2、创建资源文件夹&#xff08;根据公司业务划分&#xff09; 3、资源文件夹内创建或邀请成员 4、创建管控策略&#xff08;类型访问控制权限授权方法&#xff0c;可以授权给指定给资源文件夹或资源文件夹内成员&#xff09; 5、可信服务-委派管理员账号数量 …...

ChatGPT AI专题资料合集【65GB】

介绍 ChatGPT & AI专题资料合集【65GB】 &#x1f381;【七七云享】资源仓库&#xff0c;海量资源&#xff0c;无偿分享√...

Linux 编译安装python

以deepin操作系统安装Python3.8.10为例。 下载 python3.8.10 官网下载 Linux要下载源码&#xff0c;进行编译。 下图tarball即tar包&#xff0c;是压缩包的意思。python官网给出两种压缩格式的tarball&#xff0c;下载哪个都可以。 方式一&#xff1a;直接点击链接下载 方式…...

2025 QS 世界大学排名公布,北大清华跻身全球前20

一年一度&#xff0c;2025 QS 世界大学排名公布&#xff01; QS&#xff08;Quacquarelli Symonds&#xff09;是唯一一个同时将就业能力与可持续发展纳入评价体系的排名。 继去年 2024 QS 排名因为“墨尔本超耶鲁&#xff0c;新南悉尼高清华”而荣登微博热搜之后&#xff0c…...

clickhouse(十五、存储优化实践)

文章目录 背景问题定位优化方式排序键设计写入顺序压缩算法 DoubleDeltaLowCardinality避免使用Nullable 总结 背景 clickhouse集群容量告警&#xff0c;项目中某些表占据大量的存储空间&#xff0c;借此机会对ck的存储优化进行实践学习&#xff0c;并通过多种方式测试验证优化…...

ubuntu下搭建Supervisor

sudo apt update #安装 sudo apt install supervisor#启动 supervisord 服务&#xff1a; sudo systemctl start supervisor#关闭 supervisord 服务 sudo systemctl stop supervisor#重启 supervisord 服务 sudo systemctl restart supervisor#设置 supervisord 开机自启 sudo …...

在HTML和CSS当中运用显示隐藏

1.显示与隐藏 盒子显示:display:block;盒子隐藏: display:none:隐藏该元素并且该元素所占的空间也不存在了。 visibility:hidden:隐藏该元素但是该元素所占的内存空间还存在&#xff0c;即“隐身效果”。 2.圆角边框 在CSS2中添加圆角&#xff0c;我们不得不使用背景图像&am…...

洞口做网站的公司/衡阳seo外包

1. 平台环境搭建 1.1安装apicloud 下载APICloud Studio2(可点击https://www.apicloud.com/devtools 下载) 点击下载&#xff0c;然后解压&#xff0c;然后就可以看到apicloud-studio-2的应用程序&#xff0c;右键——发送到——桌面快捷方式&#xff08;一般以后使用&#xff0…...

做网站学多长时间可以学会/软文代写公司

好啦&#xff0c;101-200的文章阶段记录开始啦&#xff0c;新的开始&#xff0c;加油&#xff01; 上一篇文章写到了递归遍历所有文件&#xff0c;提到了压缩包的问题&#xff0c;现在就来介绍一下&#xff1a; python解压缩文件常用shutil模块 直接上代码&#xff1a; 压缩…...

如何查询网站主机信息/软文台

前一段时间有个朋友发朋友圈说&#xff1a;为什么我的抖音戒了XX个小时了&#xff0c;游戏戒了XX个小时了&#xff0c;为什么还是看书不进&#xff1f;相信不少小伙伴也会觉得看书本、资料、视频的时候太无聊了&#xff0c;也会有越看越想和周公约会的烦恼吧&#xff1f;没关系…...

东莞网站设计制作教程/google服务框架

JAVA项目实现授权部署 (一)请注意&#xff1a;这个只是个比较low的实现&#xff0c;如果那种考虑用户懂代码&#xff0c;又拿到源码的&#xff0c;别看这个了还是。对我们来说&#xff0c;拿到源码&#xff0c;没有什么破不了的&#xff0c;只不过是时间问题&#xff0c;对不&a…...

最牛的html5网站建设/电脑系统优化工具

作业代码地址&#xff1a;点我 1.分析数据 训练集 列是时间&#xff0c;一共24列&#xff0c;是每天的24小时 行是检测的特征值&#xff0c;每次会检测18个特征值&#xff0c;故每18行是一天的数据 一个月20天&#xff0c;一年12个月&#xff0c;所以一共18*20*12行的数据 …...

wordpress分页页面/seo入门版

各种排序算法&#xff08;1&#xff09;冒泡排序 选择排序 快速排序1. 冒泡排序1.1 名字由来&#xff1a;1.2 冒泡思想1.3 原理1.4 时间复杂度&#xff1a;O(n^2)1.5 空间复杂度&#xff1a;11.6 是否稳定&#xff1a;稳定1.7 代码例子2. 选择排序2.1 选择思想2.2 原理2.3 时间…...