C++STL-priority_queue的实现

news2024/11/15 23:37:09

大家好!这篇文章,主要讲解一下这个优先级队列,还包含了仿函数等等的知识。希望大家能够一起加油!!!
在这里插入图片描述

文章目录

  • 1. priority_queue的实现
    • 1.1 push函数
    • 1.2 pop函数
    • 1.3 top函数和empty函数
  • 2. 仿函数
    • 2.1 仿函数的由来和定义
    • 2.2 改造priority_queue
    • 2.3 sort的仿函数
    • 2.4 什么时候要写仿函数呢
  • 3. priority_queue的构造

1. priority_queue的实现

它在STL中是这个样子:
在这里插入图片描述
我们先不看仿函数,先把框架实现一下:
在这里插入图片描述
它的成员函数有这些,我们一个一个来实现。

1.1 push函数

在这里插入图片描述
我们这里把数据插入到容器里了,但还是不行。因为它还不是一个大堆。我们需要写一个向上调整来创建一个大堆。大堆是如何创建的呢?不懂的可以看这里:堆的创建
在这里插入图片描述
实现如下:
在这里插入图片描述
这样,每当我们插入一个数据时,它会向上调整,形成一个大堆。

1.2 pop函数

pop函数其实是删除堆的顶部元素。那么堆的删除是如何做的,我们可以看这里:堆的删除
在这里插入图片描述
实现如下:
在这里插入图片描述

1.3 top函数和empty函数

在这里插入图片描述
这里使用引用可能里面存的是像string这样的类,拷贝构造的代码比较大。加const是因为我们不能改变里面的元素,防止它不是一个堆了。
在这里插入图片描述
这两个函数比较简单,就不多说了。

我们来测试一下写的对不对:
在这里插入图片描述
我们可以看到是没有什么太大的问题。这里我们给它写死了,如果我们想升序排列,就没有办法了。这时,我们需要用仿函数的知识。

2. 仿函数

2.1 仿函数的由来和定义

我们知道,在C语言中我们使用函数指针的时候会很麻烦。而仿函数就是解决这个问题。
定义:仿函数(Functor)又称为函数对象(Function Object)是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样,不过作为仿函数的类,都必须重载 operator() 运算符。因为调用仿函数,实际上就是通过类对象调用重载后的 operator() 运算符
举个例子:
在这里插入图片描述
我们在这里写了一个less类,里面重载了()运算符。所以我们就可以这样去使用:
在这里插入图片描述
这里我们用这个less类来定义一个对象,然后用这个对象来调用重载的()运算符。从这里我们可以看到它的调用方式和函数非常的相似。这样我们也可以来比较大小。如果我们想比较不同类型的,我们可以加上模板。
在这里插入图片描述
有比小的,也会有比较大的。
在这里插入图片描述
那么这样的话,我们就可以把这个设成我们priority_queue的模板参数。当传不同的仿函数时,可以调用不同的方法。

2.2 改造priority_queue

在这里插入图片描述
然后我们可以这样来写:
在这里插入图片描述
这样默认的情况下,传的是less这个类模板,父亲比孩子小交换,也就是创建的是大堆。如果我们给它传greater类模板,父亲比孩子大交换,创建的就是小堆。
在这里插入图片描述
向下调整也是一样的道理。现在我们就来测试一下这样写行不行:
在这里插入图片描述
默认情况下是大堆,没有问题。
在这里插入图片描述
小堆也没有问题。

2.3 sort的仿函数

在这里插入图片描述
它和priority_queue的区别在priority_queue是在模板中传类型,而sort是在函数中传递这个对象
举个例子:
在这里插入图片描述
其实在这里,我们也不是说必须要传迭代器才能排序。我们也可以传普通的数组。
在这里插入图片描述
因为指向数组的原生指针,本身就是天然的迭代器

2.4 什么时候要写仿函数呢

看下面的例子:
在这里插入图片描述
对于自定义类型,我们把它们进行比较,不能直接比,我们需要自己写比较函数。
在这里插入图片描述
这里我们用的是以价格默认升序排序,但是如果我们现在想以销售的数量为升序排,该怎么办呢?它就不能灵活的排了,此时我们就需要写仿函数。
在这里插入图片描述
这样,我们就可以灵活的去比较自定义类型的各个成员变量了。

3. priority_queue的构造

我们来看一下库里的构造是如何写的:
在这里插入图片描述
我们先看第一个。其实在C++里,我们需要兼容C语言,也就是需要兼容函数指针。
举个例子:
在这里插入图片描述
这里我们写了一个函数,如果用C语言的话,我们需要用函数指针。因为priority_queue传的是类型。所以应该这样:
在这里插入图片描述
那么这里模板的话:
在这里插入图片描述
我们只知道指针的类型,不知道指针指向谁?只是定义了一个野指针,无法使用。所以在构造的时候,我们加了一个这样东西:
在这里插入图片描述
怎么写的呢?我们来看:
在这里插入图片描述
在这里插入图片描述
我们在这里加了一个成员变量。如果传的是less这种类模板,那么这个成员变量就会拷贝成这个对象,然后去调用operator()。如果传的是一个函数指针,也会定义一个对象。在C++中对内置类型升级了。
在这里插入图片描述
在这里插入图片描述
如果传的是函数指针,初始化后是一个空指针,还是不能使用。所以我们在使用的时候,还要传。
在这里插入图片描述
这样在初始化时就知道函数指针指向的是谁了。

然后,我们再来谈一下第二个构造
在这里插入图片描述
在这里插入图片描述
在一些TOP-K问题可以使用。

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

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

相关文章

【C进阶】模拟实现atoi函数

⭐博客主页:️CS semi主页 ⭐欢迎关注:点赞收藏留言 ⭐系列专栏:C语言进阶 ⭐代码仓库:C Advanced 家人们更新不易,你们的点赞和关注对我而言十分重要,友友们麻烦多多点赞+关注,你们…

day21-多线程

1.实现多线程 1.1简单了解多线程【理解】 是指从软件或者硬件上实现多个线程并发执行的技术。 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能。 1.2并发和并行【理解】 并行:在同一时刻,有多个指令在多个CP…

【数据结构】双链表实现

双链表实现双链表LinkedList的使用ArrayList 和 LinkedList的区别双链表 双链表的结点其实就是在单链表结点的基础上多了一个存储前一个节点地址的域,例如: 接下来就实现双链表的各种操作,首先定义好双链表的结构: public class…

【经典算法】双指针(尺取法):爱,是双向奔赴,还是你追我赶?

👑专栏内容:算法学习随笔⛪个人主页:子夜的星的主页💕座右铭:日拱一卒,功不唐捐 目录一、前言二、左右指针(双向奔赴)1、定义2、回文检查三、快慢指针(你追我赶&#xff…

将字符串代码编译为字节代码对象 compile()

【小白从小学Python、C、Java】【计算机等级考试500强双证书】【Python-数据分析】将字符串代码编译为字节代码对象compile()[太阳]选择题关于以下python代码表述错误的一项是?sx1y2print("xy",xy)print("【显示】s:")print(s)print("【执…

fpga实操训练(一个典型的fpga系统)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】 对于刚学习fpga的同学来说,很多人可能一开始并不了解,一个典型的fpga系统应该是什么样子的。今天正好来熟悉一下。此外,我们也可以通过这个系统,从另外一个角度学习下,为什么要…

【蓝桥杯】简单数论——快速幂矩阵快速幂

1、快速幂 1.1运算模 定义:模运算为a除以m的余数,记为a mod m,有a mod m a % m。 模运算是大数运算中的常用操作:如果一个数太大,无法直接输出,或者不需要直接输出,可以把它取模后&#xff…

2.4总线操作和定时

文章目录一、引子二、介绍1.总线周期2.总线定时规范三、同步定时方式1.过程2.特点3.优缺点①优点②缺点四、异步定时方式1.介绍2.三种方式(1)不互锁方式(2)半互锁方式(3)全互锁方式3.优缺点①优点②缺点五、…

Allegro如何统计包含过孔长度的网络长度操作指导

Allegro如何统计包含过孔长度的网络长度操作指导 当需要统计网络长度的时候,可以通过element选择nets看到网络的长度,但是当网络换层了,并且需要统计到过孔的长度,类似下图 Allegro可以快速的统计网络的长度,并且包含过孔的长度 具体操作如下 选择Setup选择Constraint –…

设计模式 - 六大设计原则之SRP(单一职责)

文章目录概述CaseBad ImplBetter Impl1. 定义接口2. 职责分离-多种实现类3. 单元测试小结概述 单一职责原则(Single Responsibility Principle, SRP)又称单一功能原则,是面向对象的五个基本原则(SOLID)之一…

2022这一年

前言 一年过得好快啊,这个年终总结不知道该写点啥,所以一直到现在也没动笔。 但如果不写吧,总感觉少了点什么。就像过年守夜,反正我是每年都要等到凌晨12点放完鞭炮后才睡。 前些天也看到不少博主发布了2022年终总结,…

【ARM体系结构】之相关概念与公司简介

1、ARM相关的概念 机器码:计算机可以识别的0和1的组合。即高低电平的信号,1高电平信号,0低电平信号 汇编指令:编译器可以将汇编指令(存在代码段)编译成为机器码,执行汇编指令可以完成相应的汇编…

【进击的算法】基础算法——动态规划

🍿本文主题:动态规划 🎈更多算法:回溯算法 💕我的主页:蓝色学者的主页 文章目录一、前言二、概念2.1概念一:状态转移2.2概念二:Dp数组三、例题3.1斐波那契数列3.1.1题目描述3.1.2状态…

JQUERY总结(四)

对象拷贝&#xff1a; <script src"jQuery.min.js"></script> <script>$(function(){// var targetObj{};// var obj{// id:0,// name:"xinyi",// location:"henan"// };// //覆盖以前的相同key值对应的数据// $.…

【自然语言处理】基于NLP的电影评论情感分析模型比较

基于NLP的电影评论情感分析模型比较一段时间以来&#xff0c;使用机器学习的 NLP 任务借助 BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;模型被认为是当前的黄金标准。这些模型通常用于我们日常的许多语言处理任务&#xff0c;比如谷…

Java面试题,线程安全问题

线程安全问题一、对线程安全的理解&#xff08;实际上是内存安全&#xff09;二、Thread类的继承、Runable接口的重写三、守护线程四、ThreadLocal原理和使用场景五、sleep、wait、join、yield六、线程池、解释线程池参数一、对线程安全的理解&#xff08;实际上是内存安全&…

JVM面试一

5. JVM 5.1 JVM包含哪几部分? 参考答案 JVM 主要由四大部分组成:ClassLoader(类加载器),Runtime Data Area(运行时数据区,内存分区),Execution Engine(执行引擎),Native Interface(本地库接口),下图可以大致描述 JVM 的结构。 JVM 是执行 Java 程序的虚拟计算…

【计算机组成原理】第一章 计算机系统概述

文章目录第一章 知识体系1.1 计算机发展历程1.1.1 计算机硬件的发展1.1.2 计算机软件的发展1.2 计算机系统层次结构1.2.1 计算机系统的组成1.2.2 计算机硬件1.2.3 计算机软件1.2.4 计算机的层次结构1.2.5 计算机系统的工作原理1.3 计算机的性能指标第一章 知识体系 1.1 计算机发…

35.Isaac教程--机械臂取放物体示例应用程序

机械臂取放物体示例应用程序 ISAAC教程合集地址文章目录机械臂取放物体示例应用程序使用 Omniverse 套件模拟驱动的机器人手臂启动取放示例应用程序该包为拾取和放置场景提供了一个应用程序脚手架。 它具有执行拾取和放置任务所需的高级步骤&#xff0c;并与两种类型的机器人操…

Java面试题,Spring与SpringBoot相关问题

Spring与SpringBoot相关问题1、BeanFactory和ApplicationContext有什么区别&#xff1f;2、描述一下Spring Bean的生命周期3、Spring的几种Bean的作用域4、单例Bean是线程安全的吗&#xff1f;5、Spring框架用到了哪些设计模式6、Spring事务的实现方式、隔离级别、传播行为7、S…