【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现

这篇具有很好参考价值的文章主要介绍了【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl

前言

点进来的小伙伴不知道学过数据结构里的堆没有,如果学过的话,那就好说了,优先级队列就是堆,如果没学过,没关系,可以参考一下我之前写的一篇关于堆的博客,可以点进去看看:【数据结构】堆(包含堆排序和TOPK问题)

那么了解过堆了的话,我就不讲那么细致了,就把STL中给的接口说一遍,然后模拟实现一下,再说一下适配器就好了。

正式开始

还是cpluplus这个网站:queue

【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl

priority_queue 基本介绍

priority_queue就是优先级队列。其头文件就是queue,但是队列和优先级队列关系不大,两个是不同的数据结构。但二者都是适配器,容器适配器。

【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
关于适配器和仿函数会在最后的时候讲。

先说基本的。

根据优先级队列的名字就可以知道其存放的数据是有优先级的。
里面就下面这几个函数:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
而且常用的就empty, size, top, push, pop。

意思就不讲了,看过我前面string、vector、list、栈和队列的话,肯定是知道这些函数是干啥的。

我就直接演示一下就好:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
用法几乎是与栈和队列一样。
但是这里是打印结果排好序了,降序。

所以,优先级队列默认情况下是大的优先。打印升序等会讲。

优先级队列的适配器

【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl

看其第二个模板参数:class Container = vector<T>
这就是容器适配器。

看过前一篇栈和队列的话估计你就懂什么意思了,如果不懂适配器是啥,可以看看:STL栈和队列

我们可以将其底层的容器改为其他的容器,像我们上一篇讲的deque就可以:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
list是不行的,至于什么行什么不行在模拟实现的时候再说。

第三个模板参数compare

【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl

其实前面几篇中用到算法库中的sort时已经见过了,但是当时并不知道其底层是啥样的,那么这篇就能了解一下了,但这里就还是先说咋用,最后模拟实现的时候再说底层。

跟sort用法很像,sort第三个参数传的是一个对象,比如说给sort传greater<int>()就是降序,而这里传的是类型,比如说传greater<int>就是小堆。可以看到,模板参数缺省值为less<typename Cntainer::value_type>,可能有的同学不知道value_type是啥,其实就是我们日常放在容器中的元素类型,就是那个T,T可以为int、char什么的都行。所以我们默认情况下参数 Container 就是less<T>的类型,那么就是大堆。

给个例子:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
这样就变成了小堆,每次取堆顶的值就是最小值。

这里要记住:
传greater时是小堆。
传less时是大堆。

这样基本用法就算讲好了,不要说这点怎么够,就几个函数,没什么好讲的,重点在后面。

带大家来做一道题。
题目链接:数组中的第K个最大元素

【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
题目中有要求,必须设计时间复杂度为O(N)的算法。

那么想到排序的同学就另寻他路吧。

这道题就可以用到优先级队列,就是堆。
先把堆建好,然后pop k-1次后的堆顶就是第k大的元素。

代码如下:

class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
    priority_queue<int> poq(nums.begin(), nums.end());

    while(--k)
        poq.pop()return poq.top();
}
};

然后就是最重要的模拟实现了。

模拟实现priority_queue

学过堆的同学应该都知道,堆的实现的核心无非就是向上调整和向下调整。

而堆虽然逻辑结构上是二叉树,但是实际物理结构就是数组。我们用C++写,默认容器就是vector,因为随机访问数据的次数比较多。我们很多地方就可以直接复用vector中的函数接口,所以就需要自己动手写两个,一个是向上调整,一个是向下调整。

先把基本的给出:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl

push和pop要用到向上调整和向下调整:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
记得这两个要设置为私有。

然后把基本的接口给出:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl

测试一下:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl

上面基本功能的是实现了,但是还是有点问题的,就是如何控制大小堆?
不能说别人用的时候还要把代码改一下才行,这样实现出来的东西也太拉垮了,能不能像库中那样,再搞一个模板参数,传一个仿函数来实现大小堆的控制。

肯定是可以的,但那么先说一下仿函数是什么。

仿函数

很简单,不要被名字吓到。

就是一个类,里面重载了()运算符。

看:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
这就是那个less。非常的简单。

用一下:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
第一个ls(1, 2)乍一看就像是函数调用,但实际上就是类对象调用了operator()。

可能看起来不是很熟悉,看这个:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
这个看起来就相对熟悉一点了,sort里传参就是红色框出来的匿名对象。

再来个greater:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
测试:

【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl

这就是仿函数,用类来重载()来实现。调用的时候就像函数一样,我们C语言阶段学过qsort,传比较的那个参数的时候要传函数指针,但是函数指针太麻烦了,所以C++为了不再用函数指针,就搞了仿函数。

那么此时我们就可以搞第三个模板参数了。
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
传的是类型。
然后把我们向上调整和向下调整中的代码改一改:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
上面的priority_queue、less、greater都是在一个命名空间FangZhang中的,所以除了vector是复用的,剩下的都是手写的,less和greater就是刚写出来的那两个,就可以直接用了。

测试一下:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
完全是可以用的。
再用一下库中的:
【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现,c++,开发语言,算法,priority_queue,stl
也是可以的。

再来强调一点。

假如说一个对象vector v,我们用sort时,传参是sort(v.begin(), v.end(), less<int>())
而这堆这是定义对象传模板参数priority_queue<int, vector<int>, less<int>>
前者是传匿名对象,后者是传类型。是不一样的。不要搞混。

差不多完了。
前面栈和队列还有这个优先级队列都是容器适配器,就是可以改变其底层所使用的容器,从而能够用不同的容器来实现其底层的函数接口。

下一篇讲迭代器适配器。

到此结束。。。文章来源地址https://www.toymoban.com/news/detail-597228.html

到了这里,关于【C++】STL优先级队列(priority_queue)功能介绍以及模拟实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++初阶】模拟实现优先级队列priority_queue

    👦个人主页:@Weraphael ✍🏻作者简介:目前学习C++和算法 ✈️专栏:C++航路 🐋 希望大家多多支持,咱一起进步!😁 如果文章对你有帮助的话 欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨ 优先级队列顾名思义就是 按优先级出队列 priority_queue 是一个容器适配器,默认使用

    2024年02月10日
    浏览(29)
  • 【C++】详解priority_queue(优先级队列)与函数对象

    目录 一、priority_queue 的介绍和使用 1.1priority_queue 的介绍 2.2priority_queue 的使用 二、仿函数 2.1什么是仿函数 2.2仿函数的作用 三、函数对象的特点(知识点多) 3.1分析特点5(比较普通函数与函数对象) 3.1.1利用普通函数传递参数 拓展之:深度剖析函数利用模板的本质 3.1.2利用

    2024年02月08日
    浏览(29)
  • C++——优先级队列(priority_queue)的使用及实现

    目录 一.priority_queue的使用 1.1、基本介绍 1.2、优先级队列的定义 1.3、基本操作(常见接口的使用) 1.4、重写仿函数支持自定义数据类型 二.priority_queue的模拟实现 2.1、构造重要的调整算法 2.2、常见接口的实现 push() pop() top() empty()、size()  三.利用仿函数改进调整算法 我们之前

    2024年02月02日
    浏览(29)
  • 优先级队列priority_queue

    关于less建大根堆,输出降序序列,greater建小根堆,输出升序序列,这点和sort()函数相反,参考我的这篇博客 底层原理 priority_queue底层维护着一个对应类型的,vector物理结构,但相当于堆排序的结构,这个vector逻辑结构是一个二叉堆; 每次 插入数据 ,我们插在堆尾(vector尾),

    2024年02月16日
    浏览(30)
  • 优先级队列priority_queue模拟实现

    🌟🌟hello,各位读者大大们你们好呀🌟🌟 🚀🚀系列专栏:【C++的学习】 📝📝本篇内容:C++容器优先级队列priority_queue模拟实现 ⬆⬆⬆⬆上一篇:string模拟实现 💖💖作者简介:轩情吖,请多多指教( •̀֊•́ ) ̖́- ①优先级队列是一种容器适配器,它的第一个元素总是

    2024年02月02日
    浏览(26)
  • [C++] STL_priority_queue(优先级队列) 的使用及底层的模拟实现,容器适配器,deque的原理介绍

    priority_queue文档介绍 翻译: 1. 优先队列是一种 容器适配器 ,根据严格的弱排序标准, 它的第一个元素总是它所包含的元素中最大的。 2. 此上下文类似于 堆 , 在堆中可以随时插入元素,并且只能检索最大堆元素(优先队列中位于顶部的元素)。 3. 优先队列被实现为容器适配

    2024年02月04日
    浏览(35)
  • 从C语言到C++_20(仿函数+优先级队列priority_queue的模拟实现+反向迭代器)

    目录 1. priority_queue的模拟实现 1.1 未完全的priority_queue 1.2 迭代器区间构造和无参构造 1.3 仿函数的介绍和使用 1.4 完整priority_queue代码: 1.5 相关笔试选择题 答案: 2. 反向迭代器 2.1 反向迭代器的普通实现 reverse_iterator.h(不对称版) 2.2 反向迭代器的对称实现 reverse_iterator.

    2024年02月10日
    浏览(38)
  • 【C++入门到精通】C++入门 —— priority_queue(STL)优先队列

    ⭕文章绑定了VS平台下std::priority_queue的源码,大家可以下载了解一下😍 前面我们讲了C语言的基础知识,也了解了一些数据结构,并且讲了有关C++的命名空间的一些知识点以及关于C++的缺省参数、函数重载,引用 和 内联函数也认识了什么是类和对象以及怎么去new一个 ‘对象

    2024年02月12日
    浏览(32)
  • C++基础(三)——STL优先级队列

    模板输入 1、元素类型 2、容器类型 3、函数对象类型 priority_queueint name; priority_queue默认为大顶堆 故定义也可以写作: priority_queueint, vectorint, lessint ay; 如果需要构建一个小顶堆,可以改变定义方式为: priority_queueint, vectorint, greaterint ay; 使用std::greater模板无需自定义比较函数。

    2024年02月09日
    浏览(43)
  • C++ STL学习之【优先级队列】

    ✨个人主页: 北 海 🎉所属专栏: C++修行之路 🎃操作环境: Visual Studio 2019 版本 16.11.17 优先级队列 priority_queue 是容器适配器中的一种,常用来进行对数据进行优先级处理,比如优先级高的值在前面,这其实就是初阶数据结构中的 堆 ,它俩本质上是一样东西,底层都是以数

    2024年02月05日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包