【C++/STL】:优先级队列(priority_queue)的使用及底层剖析仿函数

目录

  • 💡前言
  • 一,优先级队列的使用
  • 二,仿函数
    • 1,什么是仿函数
    • 2,仿函数的简单示例
  • 三,优先级队列的底层剖析

💡前言

优先队列(priority_queue)是一种容器适配器,默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意:默认情况下priority_queue是大堆

注意:使用优先级队列要包含头文件 < queue >

一,优先级队列的使用

在这里插入图片描述

代码实现如下:

这里的建堆一般有两种方式:
(1) 一种是一个一个push进vector容器再进行向上调整建堆
(2) 另一种是直接用迭代器区间构造直接建堆(推荐用这种)

#include <iostream>
#include <queue>
#include <functional>
using namespace std;void test_priority_queue()
{vector<int> v = { 6,0,3,5,4,7,9,1,2,8 };//默认升序//priority_queue<int> pq(v.begin(), v.end());//一个一个尾插建堆priority_queue<int, vector<int>, greater<int>> pq;for (auto e : v){pq.push(e);}//迭代器区间构造,直接建堆//priority_queue<int,vector<int>,greater<int>> pq(v.begin(), v.end());while (!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;}int main()
{test_priority_queue();return 0;
}

注意:优先级队列默认的大堆,降序排列,如果要升序,就要换仿函数。下图中第三个模板参数就是传仿函数。

使用算法库里的 less 和 greater 算法,需要包含头文件< functional >

在这里插入图片描述

二,仿函数

1,什么是仿函数

仿函数也叫函数对象,是一个重载了 operator() 的类,可以使得类的对象像函数一样使用

2,仿函数的简单示例

operator()并没有参数的个数和返回值,所以使用是十分灵活的

struct Func1
{//无参无返回值void operator()(){cout << "Func调用" << endl;}
};struct Func2
{//有参无返回值void operator()(int n){while (n--){cout << "Func调用" << endl;}}
};int main()
{Func1 f1;f1();  //使得对象像函数一样使用f1.operator()(); //显示调用cout << endl;Func2 f2;f2(3);  //使得对象像函数一样使用return 0;
}

在这里插入图片描述

三,优先级队列的底层剖析

namespace ling
{template<class T>class myless{public:bool operator()(const T& x, const T& y){return x < y;}};template<class T>class mygreater{public:bool operator()(const T& x, const T& y){return x > y;}};template <class T, class Container = vector<T>, class Compare = myless<T>>class priority_queue{public:priority_queue() = default;//迭代器区间构造template <class InputIterator>priority_queue(InputIterator first, InputIterator last){while (first != last){con.push_back(*first);++first;}//建堆for (int i = (con.size() - 1 - 1) / 2; i >= 0; i--){Adjust_down(i);}}bool empty() const{return con.empty();}size_t size() const{return con.size();}// 堆顶元素不允许修改,因为:堆顶元素修改可以会破坏堆的特性const T& top()const{return con[0];}//向上调整void Adjust_up(int child){int parent = (child - 1) / 2;while (child > 0){//if (con[parent] < con[child])if(comp(con[parent], con[child])){swap(con[parent], con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){con.push_back(x);Adjust_up(con.size() - 1);}//向下调整void Adjust_down(int parent){int child = parent * 2 + 1;while (child < con.size()){if (child + 1 < con.size() && comp(con[child], con[child + 1])){child += 1;}//if (con[parent] < con[child])if(comp(con[parent], con[child])){swap(con[parent], con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}void pop(){swap(con[0], con[con.size() - 1]);con.pop_back();Adjust_down(0);}private:Container con;Compare comp;};
}

测试代码

void TestQueuePriority()
{ling::priority_queue<int> q1;q1.push(5);q1.push(1);q1.push(4);q1.push(2);q1.push(3);q1.push(6);cout << q1.top() << endl;q1.pop();q1.pop();cout << q1.top() << endl;vector<int> v{ 5,1,4,2,3,6 };ling::priority_queue<int, vector<int>, ling::greater<int>> q2(v.begin(), v.end());cout << q2.top() << endl;q2.pop();q2.pop();cout << q2.top() << endl;
}

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

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

相关文章

rapidjson之内存分配器

MemoryPoolAllocator 内存池分配器 结构 #mermaid-svg-tPXDaw5Q5t1lS3Nz {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-tPXDaw5Q5t1lS3Nz .error-icon{fill:#552222;}#mermaid-svg-tPXDaw5Q5t1lS3Nz .error-text…

MindManager2024思维导图电脑版下载,你的思维管理神器!

&#x1f9e0; 思维导图界的革命性更新&#xff01; 亲爱的小红书的朋友们&#xff0c;今天我要和你们分享一个我近期发现的神器——MindManager2024思维导图软件&#xff01;这不仅仅是一个软件&#xff0c;它简直是我工作学习中的得力助手。想象一下&#xff0c;你的大脑中那…

MindManager2024思维导图软件重磅发布更新!

大家好啊&#xff01;&#x1f44b; 今天我超级激动要分享给大家一款改变我工作和学习方式的工具——MindManager2024思维导图软件&#xff01;这可不仅仅是个工具哦&#xff0c;它更像是我的私人思维助手&#xff0c;帮我整理思绪&#xff0c;规划时间&#xff0c;还能激发创新…

当你在浏览器输入一个地址

你在浏览器中输出了一个地址&#xff0c;回车后&#xff0c;一直到显示页面&#xff0c;中间经历了哪些过程 &#xff1f; 1. 用户输入 URL 并按下回车 用户在浏览器的地址栏中输入一个 URL&#xff08;例如 http://example.com&#xff09;并按下回车键。 2. DNS 解析 浏览…

猫狗识别—静态图像识别

猫狗识别—静态图像识别 1. 导入必要的库:2. 设置数据目录和模型路径:3. 定义图像转换4. 使用GPU5. 加载没有预训练权重的ResNet模型6. 创建Tkinter窗口:7.定义选择图片的函数:8.定义预测图片的函数:9.退出程序的函数:10.创建按钮:11.运行Tkinter事件循环:12. 完整代码&#xf…

JSP 开发环境搭建

JSP 开发环境搭建 1. 引言 JavaServer Pages(JSP)是一种动态网页技术,广泛用于创建交互式的网页。为了开发JSP应用程序,首先需要搭建一个合适的开发环境。本文将详细介绍如何搭建JSP开发环境,包括所需软件的安装和配置步骤。 2. 环境准备 在开始之前,请确保您的计算机…

Python高级编程:深度学习基础

Python高级编程:深度学习基础 在前几篇文章中,我们探讨了Python的基础语法、面向对象编程、标准库、第三方库、并发编程、异步编程、网络编程与网络爬虫、数据库操作与ORM、数据分析与数据可视化以及机器学习基础。在这篇文章中,我们将深入探讨Python在深度学习领域的应用。…

一级_01_计算机基础及MS Office应用

1.在计算机内部用来传送、存储、加工处理的数据或指令都是以形式进行的。 十进制码 二进制码 八进制码 十六进制码 2.磁盘上的磁道是&#xff08;&#xff09;。 一组记录密度不同的同心圆 一组记录密度相同的同心圆 一条阿基米德螺旋线 二条阿基米德螺旋线 3.下列关…

docker导入镜像添加REPOSITORY和TAG信息

docker导入镜像时添加REPOSITORY和TAG信息的命令 当你从一个tar文件导入Docker镜像时&#xff0c;原始的REPOSITORY和TAG信息不会自动附加到镜像上&#xff0c;但你可以在导入后立即使用docker tag命令手动添加这些信息。下面是整个过程的步骤概述&#xff1a; 步骤 1: 导入镜…

Chrome谷歌浏览器如何设置,才能正常使用?

Chrome浏览器&#xff0c;也被称为谷歌浏览器&#xff0c;由于简洁的界面设计&#xff0c;极快的响应速度&#xff0c;强大的插件商店&#xff0c;在全球浏览器市场份额中一直都处于遥遥领先的地位。但是因为2010年谷歌宣布退出中国&#xff0c;国内不能再使用谷歌的服务&#…

探索CSS中的cursor鼠标属性

在网页设计中&#xff0c;细节决定成败。CSS的cursor属性是这些细节中的关键一环&#xff0c;它不仅影响着网页的美观&#xff0c;更关乎用户体验。今天&#xff0c;我们就来深入了解一下cursor属性&#xff0c;看看如何通过它来增强网页的交互性。 cursor属性概览 cursor属性…

【仿真建模-解析几何】求有向线段上距指定点最近的坐标

Author&#xff1a;赵志乾 Date&#xff1a;2024-06-25 Declaration&#xff1a;All Right Reserved&#xff01;&#xff01;&#xff01; 问题描述&#xff1a; 有向线段起点A为&#xff08;x1&#xff0c;y1&#xff09;&#xff0c;终点B为&#xff08;x2&#xff0c;y2&a…

HTML+CSS 3D旋转登录表单

效果演示 实现了一个具有3D旋转效果的登录框&#xff0c;背景为太空图片&#xff0c;登录框位于太空中心&#xff0c;可以通过输入用户名和密码进行登录。登录框使用了CSS3的3D变换和动画效果&#xff0c;使其具有立体感和动态效果。同时&#xff0c;登录框的样式也经过精心设计…

sql sever 存储过程不能请求https的解决方案

此错误的原因&#xff0c;通常是因为SQL Server默认不允许非加密的HTTP请求。为了解决这个问题&#xff0c;需要配置SQL Server允许非密码的https请求&#xff0c;或者使用密码的http请求。 下面是配置SQL Server允许非加密http请求 UsE [master] ;Go EXEC sp_configure Sh…

CSS中的长度单位及其使用场景

在CSS的世界里&#xff0c;长度单位是构建布局和样式的基础。它们帮助我们精确地控制元素的大小、间距和位置。本文将介绍CSS中常用的长度单位及其适用场景&#xff0c;帮助你在网页设计中做出更明智的决策。 绝对长度单位 绝对长度单位提供了固定的长度值&#xff0c;不受显…

【Linux】进程间通信_3

文章目录 七、进程间通信1. 进程间通信分类命名管道 未完待续 七、进程间通信 1. 进程间通信分类 命名管道 管道应用的一个限制就是只能在具有共同祖先&#xff08;具有亲缘关系&#xff09;的进程间通信。如果我们想在不相关的进程之间交换数据&#xff0c;可以使用FIFO文件…

详细分析Oracle中的tnsnames.ora基本知识 以及 PLSQL如何连接(附Demo)

目录 1. tnsnames.ora2. Demo3. 实战 1. tnsnames.ora Oracle 数据库网络配置文件&#xff0c;用于配置客户端与数据库服务器之间的连接 定义网络服务名称&#xff0c;客户端可以使用这些名称连接到数据库实例 基本的路径如下&#xff1a; Windows: ORACLE_HOME\network\ad…

MySQL 数据库安装全攻略

在本文中&#xff0c;将为您详细介绍 MySQL 数据库的两种安装方式&#xff1a;编译安装和二进制安装。无论您是新手还是有一定经验的开发者&#xff0c;相信这篇文章都能为您提供有价值的参考。 一、MySQL 的编译安装 &#xff08;一&#xff09;准备工作 首先&#xff0c;如…

QThread 与QObject::moveToThread利用Qt事件循环在子线程执行多个函数

1. QThread的两种用法 第一种用法就是继承QThread&#xff0c;然后覆写 virtual void run()&#xff0c; 这种用法的缺点是不能利用信号槽机制。 第二种用法就是创建一个线程&#xff0c;创建一个对象&#xff0c;再将对象moveToThread, 这种可以充分利用信号槽机制&#xff…

MySQL 支持的多种日期和时间类型

MySQL 支持的多种日期和时间类型 MySQL 支持多种日期和时间类型&#xff0c;包括&#xff1a; 1. DATE: 存储日期值&#xff08;年、月、日&#xff09;&#xff0c;格式为 YYYY-MM-DD&#xff0c;例如&#xff1a;2024-06-11。 2. TIME: 存储时间值&#xff08;小时、分钟、秒…