C++STL-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问题可以使用。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学代码的咸鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值