『C++ - STL』之优先级队列( priority_queue )
文章目录
- 前言
- 优先级队列的结构
- 优先级队列的模拟实现
- 仿函数
- 最终代码
前言
什么是优先级队列,从该名中可以知道他一定有队列的一定属性,即先入先出(LILO),而这里的优先级则可以判断出它的另一个特点就是可以按照一定的条件将符合该条件的先进行出队,这就是优先级队列;
而在数据结构中有一个支持该操作的结构 - 堆( heap );
而在STL中,这个优先级队列( priority_queue )也正是堆;
优先级队列的结构
既然优先级队列的结构是堆,那想必结构上也不难;
堆的结构是以顺序表为基础,从而实现完全二叉树的结构;

从该容器的接函数接口中也可以知道实际上它就是个堆;
优先级队列的模拟实现
优先级队列priority_queue为一个类模板容器;
且同STL中的栈stack与队列queue一样都为适配器模式的容器,即以某个容器为基础;
template <class T, class Container = vector<T>,class Compare = less<typename Container::value_type> > class priority_queue;
其模板参数有三个分别为:
-
class T
容器所存储的数据类型 T ; -
class Container = vector<T>
容器适配器且定缺省参数默认为 vector< T >; -
class Compare = less<typename Container::value_type>
一个用来比较大小的仿函数,给定缺省参数默认为 less ,该仿函数在标准库std中;
根据文档中的信息来看,优先级队列主要的几个接口也正是数据结构中堆应有的结构;
#pragma once #include<iostream>#include<vector>#include<assert.h>using namespace std;namespace my_priority{//命名空间template<class T,class Container = std::vector<T>>//暂未设置仿函数class priority_queue{//总体框架public:void push(const T& val){//增_con.push_back(val);adjust_up(_con.size()-1);}void pop(){std::swap( _con[_con.size()-1],_con[0]);//删_con.pop_back();adjust_down(0);}bool empty(){//判空return _con.empty();}size_t size(){//返回大小return _con.size();}const T& top()const{//返回堆顶assert(!_con.empty());return _con[0];}void swap(priority_queue& con){//交换if(_con!=con._con)_con.swap(con._con);}private://必要函数 - 向上调整&&向下调整void adjust_up(size_t child){size_t parent = child;while(parent>0){parent = (child-1)/2;if(_con[parent]<_con[child]){std::swap(_con[parent],_con[child]);}child = parent;}}void adjust_down(size_t parent){Compare comfunc;size_t child = parent*2+1;while(child<_con.size()){if(child+1<_con.size()&&_con[child]<_con[child+1]){++child;}if(_con[parent]<_con[child]){std::swap(_con[parent],_con[child]);}parent = child;child = parent*2+1;}}Container _con; //容器适配器所实例化的对象,当前代码为vector<int>};
但是在库中,模板参数共有三个,具体的第三个仿函数到底是什么?
仿函数
仿函数,也被称为函数对象;
即一个可以使用函数功能的类,本质上就是在类中重载了operator();
举个简单的例子,当我们想要写一个能将两个数进行相加的仿函数即可以这么写;
struct Add{int operator()(int a,int b){return a+b;}
}
int main()
{Add addfunc;int ret = addfunc(1,2);//仿函数的调用;ret = Add() (1,2);//利用匿名对象;return 0;
}
同理,也可以根据该方法写一个比较两个对象大小的仿函数;
为了能接受多种类型的数据进行比较也可以将其设置为类模板;
template<class T>
struct less{bool operator()(const T& a,const T& b){return a<b;}
这也就是在实现当中缺失的模板参数,仿函数;
由于优先级队列priority_queue的大小根堆属性是由其中的向上调整算法adjust_up与向下调整算法adjust_down来决定的(建堆以及堆的调整);所以只要将对应的比较大小><换成仿函数即可;
最终代码
#pragma once #include<iostream>#include<vector>#include<assert.h>using namespace std;namespace my_priority{template<class T>struct less{bool operator()(const T& v1,const T& v2){return v1<v2;}};template<class T>struct greater{bool operator()(const T& v1,const T& v2){return v1>v2;}};template<class T,class Container = std::vector<T> ,class Compare = less<T>>class priority_queue{public:void push(const T& val){_con.push_back(val);adjust_up(_con.size()-1);}void pop(){std::swap( _con[_con.size()-1],_con[0]);_con.pop_back();adjust_down(0);}bool empty(){return _con.empty();}size_t size(){return _con.size();}const T& top()const{assert(!_con.empty());return _con[0];}void swap(priority_queue& con){if(_con!=con._con)_con.swap(con._con);}private:void adjust_up(size_t child){Compare comfunc;size_t parent = child;while(parent>0){parent = (child-1)/2;if(comfunc(_con[parent],_con[child])){std::swap(_con[parent],_con[child]);}child = parent;}}void adjust_down(size_t parent){Compare comfunc;size_t child = parent*2+1;while(child<_con.size()){if(child+1<_con.size()&&comfunc(_con[child],_con[child+1])){++child;}if(comfunc(_con[parent],_con[child])){std::swap(_con[parent],_con[child]);}parent = child;child = parent*2+1;}}Container _con;};
相关文章:
『C++ - STL』之优先级队列( priority_queue )
文章目录 前言优先级队列的结构优先级队列的模拟实现仿函数 最终代码 前言 什么是优先级队列,从该名中可以知道他一定有队列的一定属性,即先入先出(LILO),而这里的优先级则可以判断出它的另一个特点就是可以按照一定的条件将符合该条件的先进…...
简述什么是服务端包含(Server Side Include)?
Server-side include(服务器端包括)是浏览器向服务器请求您的文档时并入您的文档的一个文件。 当访问者浏览器请求含有 include(包括)指令的文档时,服务器处理 include(包括)指令并创建新的文档,在新文档中 include(包括)指令被所包括的文件内容取代。然后服务器将此…...
领英如何注册?2023超全面详细教程
领英是一家面向商业用户的全球最大的职业社交网站,据统计,Linkedln用户每月与网页的交互次数超过10亿次。对于跨境人来说,他更是作为一个开发客户、广告营销的工具,被称为跨境的“风口”。 一、领英被封原因 1、IP、设备问题 1&…...
Spring Cloud Gateway 使用 Redis 限流使用教程
从本文开始,笔者将总结 spring cloud 相关内容的教程 版本选择 为了适应 java8,笔者选择了下面的版本,后续会出 java17的以SpringBoot3.0.X为主的教程 SpringBoot 版本 2.6.5 SpringCloud 版本 2021.0.1 SpringCloudAlibaba 版本 2021.0.1.…...
Qt事件系统 day7
Qt事件系统 day7 事件系统 在Qt中,事件是派生自抽象QEvent类的对象,它表示应用程序内发生的事情或应用程序需要知道的外部活动的结果。事件可以由QObject子类的任何实例接收和处理,但它们与小部件尤其相关。Qt程序需要在main()函数创建一个…...
微服务拆分的思考
一、前言 前面几篇文章介绍了微服务核心的两个组件:注册中心和网关,今天我们来思考一下微服务如何拆分,微服务拆分难度在于粒度和层次,粒度太大拆分的意义不大,粒度太小开发、调试、运维会有很多坑。 二、微服务划分…...
DateUtil工具类记录
为支持日常工作需要,记录所用到的一些关于时间的工具类方法。随时进行补充。 /*** Description:获取两个日期之间的天数差* Author:hanyq* Date:2023/9/19 11:23*/public static int getDateDifference(Date startDate,Date endDate){int days 0;try {Calendar st…...
可信执行环境简介:ARM 的 TrustZone
目录 可信执行环境安全世界与普通世界 - 上下文切换机制ARMv7 中的异常处理ARMv8 中的异常处理 信任区商业实施TrustZone 本身的漏洞高通Trustonic 信任区强化的弱点结论声明 可信执行环境 具有信任区的 ARM 处理器实现了架构安全性每个物理处理器内核提供两个虚拟的扩展 核心…...
【音视频流媒体】 3、ffmpeg、ffplay、ffprobe 超详细介绍
文章目录 一、ffmpeg1.1 安装1.2 基本参数 二、ffprobe2.1 查编码格式2.2 查视频时长 五、视频转流5.1 MP4转H2645.2 H264转MP45.3 AVI转MP45.4 MP4转H265 六、视频文件6.1 播放6.2 filter 过滤器6.2.1 crop 6.3 视频截取6.4 视频拼接6.5 获取分辨率 七、视频和图7.1 视频抽帧7…...
解决kong部署自定义插件报 helloworld plugin is enabled but not installed
背景 我使用的是docker环境部署,使用的是自定义挂载plugins路径 -e "KONG_LUA_PACKAGE_PATH/plugins/?.lua" \ -v "/plugins:/plugins" \ -e "KONG_PLUGINSbundled,helloworld" \但是当我只需docker run的时候就报错 [error] 1#0:…...
动态数据源自定义SqlSessionFactoryBean时mybatis plus配置失效
环境: 动态数据源spring-boot 2.7.15mybatis-plus 3.5.2 yaml配置: spring:datasource:db100:username: xxxpassword: xxxjdbc-url: jdbc:kingbase8://xxx.xxx.xxx.xxx:54321/100driver-class-name: com.kingbase8.Driver# url: jdbc:postgresql://xxx…...
【Qt控件之QDialogButtonBox】概述及使用
概述 QDialogButtonBox类是一个小部件,它以适合当前小部件样式的布局呈现按钮。 对话框和消息框通常以符合该台界面指南的布局呈现按钮。不同的平台会有不同的对话框布局。QDialogButtonBox允许发人员向其添加按钮,并将自使用用户的桌面环境所适合的布局…...
IPv6知识概述 - ND协议
IPv6知识概述 - ND协议 参考文章:https://blog.csdn.net/Gina_wj/article/details/106708770 IPv6基础篇(四):邻居发现协议NDP ND协议功能概述 ND(Neighbor Discovery,邻居发现)协议是IPv6的…...
react-redux的connect函数实现
react-redux对store订阅的实现原理: storeContext.js import { createContext } from "react";export const StoreContext createContext() connect.js import React, { PureComponent } from react // import store from ../../store; import {Stor…...
Vue3使用Vite创建项目
node版本:node -v v18.16.0 npm版本: npm -v 9.5.1 Vite Vite:是一种新型前端构建工具,能够显著提升前端开发体验 脚手架,创建Vue项目,替代 Vue-cli 基于Vite创建vue项目: 1.npm create vitelatest 2.完…...
NCV7724DQBR2G车规级半桥电机驱动芯片-专为汽车,工业自动化应用提供完美解决方案
车规级半桥电机驱动芯片是一种用于驱动直流电机的芯片,常用于电动汽车、电动自行车等领域。它可以控制电机的转速和方向,并且具有过流保护、过温保护等功能,可以保证电机的安全运行。 NCV7724DQBR2G是一款车规级八通道半桥驱动器,…...
NSS [GWCTF 2019]枯燥的抽奖
NSS [GWCTF 2019]枯燥的抽奖 开题让我猜字符串,这种题目肯定不是猜,应该是类似于php伪随机数。 dirsearch扫他一下。 访问/check.php得到源码。 分析一下代码。 通过PHP伪随机数从字符库$str_long1中选取20个字符组成字符串,返回给我们前十…...
微信小程序会议OA系统
Flex弹性布局 Flex弹性布局是一种 CSS3 的布局模式,也叫Flexbox。它可以让容器中的元素按一定比例自动分配空间,使得它们在不同宽度、高度等情况下仍能保持整齐和密集不间隙地排列。 在使用Flexbox弹性布局时,首先需要创建一个容器和若干个…...
CICD:Circle CI 实现CICD
持续集成解决什么问题 提高软件质量效率迭代便捷部署快速交付、便于管理 持续集成(CI) 集成,就是一些孤立的事物或元素通过某种方式集中在一起,产生联系,从而构建一个有机整体的过程。 持续,就是指长期…...
竞赛 深度学习YOLO安检管制物品识别与检测 - python opencv
文章目录 0 前言1 课题背景2 实现效果3 卷积神经网络4 Yolov55 模型训练6 实现效果7 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 **基于深度学习YOLO安检管制误判识别与检测 ** 该项目较为新颖,适合作为竞赛课题方向&…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
