C++之STL-priority_queue和仿函数的讲解

目录

一、priority_queue的介绍和使用

1.1 priority_queue的介绍

1.2 priority_queue的基本接口

二、仿函数的介绍

2.1 基本概念

2.2 适用场景

三、模拟实现priority_queue

3.1 向上调整算法

3.2 向下调整算法

3.3 整体框架


一、priority_queue的介绍和使用

1.1 priority_queue的介绍

  1. 优先队列是一种容器适配器,根据严格的弱排序标准,它的第一个元素总是它所包含的元素中最大的。
  2. 此上下文类似于堆,在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。
  3. 优先队列被实现为容器适配器,容器适配器即将特定容器类封装作为其底层容器类,queue提供一组特定的成员函数来访问其元素。元素从特定容器的“尾部”弹出,其称为优先队列的顶部。
  4. 底层容器可以是任何标准容器类模板,也可以是其他特定设计的容器类。容器应该可以通过随机访问迭代器访问,并支持以下操作:

empty():检测容器是否为空
size():返回容器中有效元素个数
front():返回容器中第一个元素的引用
push_back():在容器尾部插入元素 

pop_back():删除容器尾部元素

     5. 标准容器类vector和deque满足这些需求。默认情况下,如果没有为特定的priority_queue类           实例化指定容器类,则使用vector。
     6. 需要支持随机访问迭代器,以便始终在内部保持堆结构。容器适配器通过在需要时自动调用           算法函数make_heap、push_heap和pop_heap来自动完成此操作。

1.2 priority_queue的基本接口

函数声明接口说明

priority_queue()/priority_queue(first,

last)
构造一个空的优先级队列

empty( )

检测优先级队列是否为空,是返回true,否则返

false

top( )返回优先级队列中最大(最小元素),即堆顶元素

push(x)在优先级队列中插入元素x

pop()删除优先级队列中最大(最小)元素,即堆顶元素

 如有不清晰的,可以去查看http://cplusplus.com具体的文档

二、仿函数的介绍

2.1 基本概念

       仿函数是一种可被调用的对象,它可以像函数一样被使用。在C++中,仿函数是一种重载了函数调用运算符 operator() 的类或结构体,它可以被当作函数来调用,接受参数并返回结果。
       在刚刚我们所讲的priority_queue就可以看到仿函数的使用:

       看这个 less 这个模板参数,它其实就是一个仿函数接口,这里我们简单的介绍一下less

        less这个仿函数实现的功能其实就是让我们的优先队列按降序排列即大堆,与之相对应的就是greater这个仿函数,其被引入进优先队列的作用是让其数据按升序排列即小堆。

大概懂了仿函数是个什么样的东西,那我们大概的来模拟实现less一下吧。

class less
{bool opeartor()(int x,int y){return x<y;}
}

       写仿函数需要注意,他一定是用class进行修饰的,且其主要是对()进行的重载,我们写的这个less只适用于整型未免太单调了,我们不妨给他加个模板。

template<class T>
class less
{bool opeartor()(T x,T y){return x<y;}
}

2.2 适用场景

  1. 首先就是priority_queue这个容器需要仿函数这个接口,当我们使用自定义类型时,需要我们自己编写一个仿函数接口。
  2. 再比如说使用 sort 时,其同样有一个仿函数的接口,举例:

实现一个升序排序:

vector<int> st={1,9,8,5,6,7,3,2,1,4};

sort(st.begin(),st.end(),greater<int>);

三、模拟实现priority_queue

       要知道priority_queue实际上是一个堆,既然是堆,那就会涉及到我们的向上调整算法和向下调整算法,这也是我们的主要编写内容。

3.1 向上调整算法

        void adjust_up(int child){int parent = (child - 1) / 2;while (parent >= 0){if (comp(c[parent], c[child])){std::swap(c[parent], c[child]);}elsebreak;child = parent;parent = (child - 1) / 2;}}

       这里可以发现我们的比较方法是使用的仿函数,这样就可以根据我们传入的仿函数的不同来定义不同的堆,是不是很方便。
这里如果不是很懂的话可以去查看一下堆的知识。

3.2 向下调整算法

        void adjust_down(int parent){int child = parent * 2 + 1;while (child < size()){if (child+1<size()&&comp(c[child], c[child+1])){child += 1;}if (comp(c[parent], c[child])){std::swap(c[child], c[parent]);}elsebreak;parent = child;child = parent * 2 + 1;}}

可不要忘了向下调整算法的边界判断哦。

3.3 整体框架

接口实现方面,和之前的内容差不多,这里我直接给大家上代码

namespace bit
{template <class T, class Container = vector<T>, class Compare = less<T> >class priority_queue{public:void adjust_up(int child){int parent = (child - 1) / 2;while (parent >= 0){if (comp(c[parent], c[child])){std::swap(c[parent], c[child]);}elsebreak;child = parent;parent = (child - 1) / 2;}}void adjust_down(int parent){int child = parent * 2 + 1;while (child < size()){if (child+1<size()&&comp(c[child], c[child+1])){child += 1;}if (comp(c[parent], c[child])){std::swap(c[child], c[parent]);}elsebreak;parent = child;child = parent * 2 + 1;}}priority_queue(){}template <class InputIterator>priority_queue(InputIterator first, InputIterator last):c(first,last){for (int i = (size() - 1 - 1) / 2; i >= 0; i--){adjust_down(i);}}bool empty() const{return c.empty();}size_t size() const{return c.size();}const T& top() const{return c[0];}void push(const T& x){c.push_back(x);adjust_up(size() - 1);}void pop(){std::swap(c[0], c[size() - 1]);c.pop_back();adjust_down(0);}private:Container c;Compare comp;};};

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

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

相关文章

基于卷积神经网络的一维信号降噪(简单版,MATLAB)

简单演示一下基于卷积神经网络的一维信号降噪&#xff0c;有个大致印象即可。 %% Plot the previous training CNN. set_plot_defaults(on) load(denoiser_sparse.mat); h1{1} double(conv1); h1{2} double(conv2); h1{3} reshape(double(conv3),[8,1,17]); figure(1) [r,c…

Java_异常

介绍 编译时异常&#xff1a; 除RuntimeException和他的子类&#xff0c;其他都是编译时异常。编译阶段需要进行处理&#xff0c;作用在于提醒程序眼 运行时异常&#xff1a; RuntimeException本身和其所有子类&#xff0c;都是运行时异常。编译阶段不报错&#xff0c;是程序…

python之enumerate()函数使用总结

enumerate() 函数是一个内置函数&#xff0c;用于在迭代过程中同时获取元素的索引和值。它返回一个枚举对象&#xff0c;包含了索引和对应的元素。 1. enumerate() 函数的语法 如下&#xff1a; enumerate(iterable, start0) 参数说明&#xff1a; iterable&#xff1a;必需…

C++怎样产生随机数

C怎样产生随机数? 这里要用到的是 rand() 函数和 srand() 函数 rand() 会返回一随机数值, 范围在 0 至 RAND_MAX ,RAND_MAX 定义在 stdlib.h, 其值根据系统配置设定 例如&#xff1a; #include<stdio.h> #include<stdlib.h> int main() {for(int i0;i<10;i)…

Java17 --- SpringCloud之Nacos

目录 一、下载nacos并运行 1.1、创建9001微服务作为提供者 1.2、创建80微服务作为消费者 二、naocs配置中心规则与动态刷新 2.1、创建3377微服务 2.2、在nacos中创建配置文件 三、nacos数据模型之Namespace-Group-Datald 3.1、DatalD方案 3.2、Group方案 3.3、Name…

python软件开发遇到的坑-相对路径文件读写异常,不稳定

1. os.chdir()会影响那些使用相对路径读写文件的程序&#xff0c;使其变得不稳定&#xff0c;默认情况下&#xff0c;当前工作目录是主程序所在目录&#xff0c;使用os.chdir会将当前工作目录修改到其他路径。 资料&#xff1a; python相对路径写对了却报错是什么原因呢&#…

前端工程化之---git hooks

git hook 和 husky 1、git hook 让我们可以在 git 执行一些行为的前后时机&#xff0c;执行一些脚本。 2、比如 pre-commit &#xff0c;能够在我们真正提交 commit 之前先执行一段代码&#xff0c;如果这段代码报错&#xff08;exit 1&#xff09;&#xff0c;提交会被取消&…

蜜蜂收卡系统 加油卡充值卡礼品卡自定义回收系统源码 前后端开源uniapp可打包app

本文来自&#xff1a;蜜蜂收卡系统 加油卡充值卡礼品卡自定义回收系统源码 前后端开源uniapp可打包app - 源码1688 卡券绿色循环计划—— 一项旨在构建卡券价值再利用生态的社会责任感项目。在当前数字化消费日益普及的背景下&#xff0c;大量礼品卡、优惠券因各种原因未能有效…

mib browser读取mib文件的oid(飞塔防火墙为例)

在配置zabbix监控的时候,配置监控项最为麻烦,一般我们都会套用模板,这种方式比较简单,但是有些设备就是没有现成的zabbix模板,怎么办? 今天我们使用MIB Browser来获取设备SNMP的OID,然后加入zabbix 。 1.什么是MIB Browser SNMP客户端工具MIB Browser, 全名iReasonin…

ARP详解

2.4 ARP 如图2-10所示&#xff0c;当网络设备有数据要发送给另一台网络设备时&#xff0c;必须要知道对方的网络层地址&#xff08;即IP地址&#xff09;。IP地址由网络层来提供&#xff0c;但是仅有IP地址是不够的&#xff0c;IP数据报文必须封装成帧才能通过数据链路进行发送…

RuntimeError: Tensor must have a last dimension with stride 1

我在使用torch.view_as_complex将weight转化为复数时&#xff0c;遇到了这样一个错误&#xff1a;由于我在对weight使用view_as_complex之前使用了F.interpolate函数进行了分辨率调整&#xff0c;因此只需对张量weight添加.contiguous()即可。

安卓抓包总结

背景 接手公司项目安卓xhs项目&#xff0c;该项目为android数据采集接口&#xff0c;该接口目前只能调用一次&#xff0c;然后就被平台风控&#xff0c;导致无法使用&#xff0c;需要恢复该接口继续使用&#xff0c;所以需要抓包分析调用的接口&#xff0c;对比接口参数和请求都…

拿到B端系统设计需求该如何入手,这样做准没错!

在拿到B端系统设计需求后&#xff0c;以下是一些入手的步骤和方法&#xff1a; 理解需求 首先&#xff0c;仔细阅读和理解所提供的需求文档。了解系统的目标、功能需求、用户需求、非功能需求等方面的要求。如果有任何不清楚或模糊的地方&#xff0c;及时与需求提出方进行沟通…

vue+sortablejs来实现列表拖拽——sortablejs的使用

sortablejs官网:https://sortablejs.com/ 最近在看form-builder组件&#xff0c;发现里面有用到sortablejs插件&#xff0c;用于实现拖拽效果。 但是这个官网中的配置&#xff0c;实在是看不懂&#xff0c;太简单又太复杂&#xff0c;不实用。 下面记录一下我的使用&#xff…

Redis 实战之RDB文件结构

RDB文件结构 databases 部分key_value_pairs 部分value 的编码字符串对象列表对象集合对象哈希表对象有序集合对象INTSET 编码的集合ZIPLIST 编码的列表、哈希表或者有序集合 总结AOF持久化的实现命令追加 AOF 文件的写入与同步小结 在本章之前的内容中&#xff0c; 我们介绍了…

C++优先级队列priority_queue模拟实现

priority_queue模拟实现 1. priority_queue介绍2. priority_queue使用2.1 priority_queue显示定义2.2priority_queue接口使用 3. 仿函数4. priority_queue模拟实现4.1 向上调整算法4.2 向下调整算法4.3 实现priority_queue的接口4.4 使用[仿函数](https://legacy.cplusplus.com…

Springboot+Vue项目-基于Java+MySQL的流浪动物管理系统(附源码+演示视频+LW)

大家好&#xff01;我是程序猿老A&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f49e;当前专栏&#xff1a;Java毕业设计 精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f380; Python毕业设计 &…

MCP3008-I/SL 模数转换器ADC SPI接口 模拟信号采集

MCP3008-I/SL 模数转换器ADC 贴片SOIC16 MCP3008-I/SL 是一款模数转换器&#xff08;ADC&#xff09;&#xff0c;属于 SAR&#xff08;逐次逼近寄存器&#xff09;架构的 ADC。它具有以下特点&#xff1a; 8 通道单 ADC 最大采样率&#xff1a;200ksps&#xff08;千样点每秒…

为什么byte 的取值范围是 [-128,127]

在计算机中&#xff0c;byte&#xff08;字节&#xff09;是存储数据的基本单位&#xff0c;通常用8位二进制数字表示一个字节。在字节中&#xff0c;最高位的最左边一位是符号位&#xff0c;用来表示正负号&#xff0c;值为0表示正数&#xff0c;值为1表示负数。 如果将byte定…

URL过滤

什么是URL过滤&#xff1f; URL过滤是一种针对用户的URL请求进行上网控制的技术&#xff0c;通过允许或禁止用户访问某些网页资源&#xff0c;达到规范上网行为和降低安全风险的目的。 URL过滤可以基于URL分类、特定URL等多种方式限制URL访问。 URL过滤的主要作用如下&#xf…