【C++/STL】:优先级队列的使用及底层剖析仿函数

目录

  • 💡前言
  • 一,优先级队列的使用
  • 二,仿函数
    • 1,什么是仿函数
    • 2,仿函数的简单示例
  • 三,优先级队列的底层剖析

💡前言

优先队列(priority_queue)是一种容器适配器,默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。注意:默认情况下priority_queue是大堆

注意:使用优先级队列要包含头文件 < queue >

一,优先级队列的使用

在这里插入图片描述

代码实现如下:

这里的建堆一般有两种方式:
(1) 一种是一个一个push进vector容器再进行向上调整建堆
(2) 另一种是直接用迭代器区间构造直接建堆(推荐用这种)

#include <iostream>
#include <queue>
#include <functional>
using namespace std;void test_priority_queue()
{vector<int> v = { 6,0,3,5,4,7,9,1,2,8 };//默认升序//priority_queue<int> pq(v.begin(), v.end());//一个一个尾插建堆priority_queue<int, vector<int>, greater<int>> pq;for (auto e : v){pq.push(e);}//迭代器区间构造,直接建堆//priority_queue<int,vector<int>,greater<int>> pq(v.begin(), v.end());while (!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;}int main()
{test_priority_queue();return 0;
}

注意:优先级队列默认的大堆,降序排列,如果要升序,就要换仿函数。下图中第三个模板参数就是传仿函数。

使用算法库里的 less 和 greater 算法,需要包含头文件< functional >

在这里插入图片描述

二,仿函数

1,什么是仿函数

仿函数也叫函数对象,是一个重载了 operator() 的类,可以使得类的对象像函数一样使用

2,仿函数的简单示例

operator()并没有参数的个数和返回值,所以使用是十分灵活的

struct Func1
{//无参无返回值void operator()(){cout << "Func调用" << endl;}
};struct Func2
{//有参无返回值void operator()(int n){while (n--){cout << "Func调用" << endl;}}
};int main()
{Func1 f1;f1();  //使得对象像函数一样使用f1.operator()(); //显示调用cout << endl;Func2 f2;f2(3);  //使得对象像函数一样使用return 0;
}

在这里插入图片描述

三,优先级队列的底层剖析

namespace ling
{template<class T>class myless{public:bool operator()(const T& x, const T& y){return x < y;}};template<class T>class mygreater{public:bool operator()(const T& x, const T& y){return x > y;}};template <class T, class Container = vector<T>, class Compare = myless<T>>class priority_queue{public:priority_queue() = default;//迭代器区间构造template <class InputIterator>priority_queue(InputIterator first, InputIterator last){while (first != last){con.push_back(*first);++first;}//建堆for (int i = (con.size() - 1 - 1) / 2; i >= 0; i--){Adjust_down(i);}}bool empty() const{return con.empty();}size_t size() const{return con.size();}// 堆顶元素不允许修改,因为:堆顶元素修改可以会破坏堆的特性const T& top()const{return con[0];}//向上调整void Adjust_up(int child){int parent = (child - 1) / 2;while (child > 0){//if (con[parent] < con[child])if(comp(con[parent], con[child])){swap(con[parent], con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}void push(const T& x){con.push_back(x);Adjust_up(con.size() - 1);}//向下调整void Adjust_down(int parent){int child = parent * 2 + 1;while (child < con.size()){if (child + 1 < con.size() && comp(con[child], con[child + 1])){child += 1;}//if (con[parent] < con[child])if(comp(con[parent], con[child])){swap(con[parent], con[child]);parent = child;child = parent * 2 + 1;}else{break;}}}void pop(){swap(con[0], con[con.size() - 1]);con.pop_back();Adjust_down(0);}private:Container con;Compare comp;};
}

测试代码

void TestQueuePriority()
{ling::priority_queue<int> q1;q1.push(5);q1.push(1);q1.push(4);q1.push(2);q1.push(3);q1.push(6);cout << q1.top() << endl;q1.pop();q1.pop();cout << q1.top() << endl;vector<int> v{ 5,1,4,2,3,6 };ling::priority_queue<int, vector<int>, ling::greater<int>> q2(v.begin(), v.end());cout << q2.top() << endl;q2.pop();q2.pop();cout << q2.top() << endl;
}

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

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

相关文章

在 notebook 中输入代码 `%matplotlib inline` 是什么意思?

在 Jupyter Notebook 中输入代码 %matplotlib inline 是一种魔法命令&#xff0c;它用于配置 Matplotlib 库的显示方式。具体来说&#xff0c;它会在 Notebook 单元格内嵌绘图&#xff0c;使生成的图表直接显示在 Notebook 的单元格输出中&#xff0c;而不是弹出一个单独的窗口…

Pytest学习(2) ---- 用例执行

https://www.cnblogs.com/saryli/p/14657823.html 先保存一下吧 还学到这里哈哈

Pbootcms留言“提交成功”的提示语怎么修改

我们在用到pbootcms建站时候&#xff0c;其中有个留言功能&#xff0c;提交成功后会提示&#xff1a;提交成功&#xff08;如下图所示&#xff09;&#xff0c;那么我们要修改这个提示语要怎么操作呢&#xff1f; 如果需要修改的话&#xff0c;直接找到文件/apps/home/control…

【Android】【Compose】Compose里面的Row和Column的简单使用

内容 Row和Column的简单使用方式和常用属性含义 Row 在 Jetpack Compose 中&#xff0c;Row 是一种用于在水平方向排列子元素的布局组件。它类似于传统 Android 中的 LinearLayout&#xff0c;但更加灵活和强大。 Row的代码 Composable inline fun Row(modifier: Modifier…

最新扣子(Coze)实战案例:图像流工具之空间风格化,完全免费教程

&#x1f9d9;‍♂️ 大家好&#xff0c;我是斜杠君&#xff0c;手把手教你搭建扣子AI应用。 &#x1f4dc; 本教程是《AI应用开发系列教程之扣子(Coze)实战教程》&#xff0c;完全免费学习。 &#x1f440; 关注斜杠君&#xff0c;可获取完整版教程。&#x1f44d;&#x1f3f…

Python的Django部署uwsgi后自签名实现的HTTPS

通过SSL/TLS来加密和客户端的通信内容。提高网络安全性&#xff0c;但是会损耗部分的服务器资源。 HTTPS 的原理图。 web.key 是打死也不能给其他人的。一定要保存好。里面主要是私钥。是各种认证的根基。本地测试的话生成1024的即可&#xff0c;如果是生产环境推荐使用2048。…

高级运维工程师讲述银河麒麟V10SP1服务器加固收回权限/tmp命令引起生产mysql数据库事故实战

高级运维工程师讲述银河麒麟V10SP1服务器加固收回权限/tmp命令引起生产MySql数据库事故实战 一、前言 作为运维工程师经常会对生产服务器进行安全漏洞加固&#xff0c;一般服务厂商、或者甲方信息安全中心提供一些安全的shell脚本&#xff0c;一般这种shell脚本都是收回权限&…

查看当前服务器Kafka是否已启动

# 查看当前系统中的java进程 # -ml 详细内容 jps -ml | grep Kafka

解决类重复的问题

1.针对AndroidX 类重复问题 解决办法&#xff1a; android.useAndroidXtrue android.enableJetifiertrue2.引用其他sdk出现类重复的问题解决办法&#xff1a;configurations {all { // You should exclude one of them not both of themexclude group: "com.enmoli"…

mac. mysql 设置查询结果直接写入文件

文章目录 需求复现设置mysql数据库sessionglobal 需求复现 我们需要将mysql查询的结果直接以csv格式的形式写入文件系统&#xff0c;以便能够使用其他脚本语言读入并进行分析&#xff0c;此时我们可以使用如下sql代码进行操作&#xff1a; select a,b, ... INTO OUTFILE file…

《人人都是产品经理》:项目坎坷的一生(下)

《人人都是产品经理》&#xff1a;项目坎坷的一生&#xff08;下&#xff09; 文档只是手段模板的作用多人协作与版本管理 流程只不过是手段这么多评审&#xff0c;可以省嘛&#xff1f; 敏捷更是手段有计划、更拥抱变化迭代周期内尽量不增加任务 集中工作、小步快跑持续细化需…

QT4-QT5-QString-const char* 之间的转换

最好所有QT项目 文件编码&#xff1a; UTF-8 QString 编码: UTF-8 const char* 编码&#xff1a; UTF-8 1.QString 有2种编码: UTF-8 GBK 默认的是UTF-8 1.1 QString : GBK ->…

开放式耳机哪个牌子好?2024热门红榜开放式耳机测评真实篇!

当你跟朋友们聊天时&#xff0c;他们经常抱怨说长时间戴耳机会令耳朵感到不适,后台也有很多人来滴滴我&#xff0c;作为一位致力于开放式耳机的测评博主&#xff0c;在对比了多款开放式耳机之后&#xff0c;你开放式耳机在保护听力方面确实有用。开放式的设计有助于减轻耳道内的…

Hive 实操案例一:统计 Top10 视频观看数

一、数据表结构 视频表 t_video 字段注释描述videoId视频唯一 id(String)11 位字符串uploader视频上传者(String)上传视频的用户名 Stringage视频年龄(int)视频在平台上的整数天category视频类别(Array<String>)上传视频指定的视频分类length视频长度(Int)整形…

【EXCEL技巧】Excel如何将数字前面的0去掉

Excel文件中经常会遇到数据是0001345这种&#xff0c;那么&#xff0c;如何将数字前面的0去掉呢&#xff1f;今天和大家分享方法。 首先&#xff0c;选中一列空的单元格&#xff0c;然后在单元格中输入公式TEXT(D3,0)&#xff0c;这里的D3指的是前面带有0的数据的位置 回车之后…

数组:移除元素

参考资料&#xff1a;代码随想录 本题思路&#xff1a;通过快慢指针将两次循环减少到一次 class Solution {public int removeElement(int[] nums, int val) {//0 1 2 2 2 2 3int fast 0;int slow 0;while(fast < nums.length){if(nums[fast] ! val){nums[slow] nums[f…

DAMA学习笔记(三)-数据架构

1.引言 架构是构建一个系统&#xff08;如可居住型建筑&#xff09;的艺术和科学&#xff0c;以及在此过程中形成的成果——系统本身。用通俗的话说&#xff0c;架构是对组件要素有组织的设计&#xff0c;旨在优化整个结构或系统的功能、性能、可行性、成本和用户体验。 对于架…

Django ModelForm 初识:简化表单处理和数据验证

ModelForm 是 Django 提供的一个强大工具,它可以根据已定义的模型自动生成表单字段。这不仅简化了表单的创建过程,还确保了表单字段与数据库模型的一致性。本文将介绍 ModelForm 的基本用法及其优势。 1. 模型定义 首先,让我们看一下我们的用户模型定义: # models.py fr…

制作TTS前端模型数据集,预训练bert模型的字典数据是怎么调用的-chatgpt问答生成

制作TTS前端模型数据集&#xff0c;预训练bert模型的字典数据是怎么调用的 1. tokenizer AutoTokenizer.from_pretrained("bert-base-chinese")命令解释结果和作用分词器的作用示例使用总结 2. toks tokenizer.encode(arr[i], add_special_tokensFalse)具体解析命令…

如何在SOLIDWORKS中高效管理文件属性?

当我们完成零件设计&#xff0c;出工程图后&#xff0c;发现零件中部分属性值需修改&#xff0c;或漏掉一些属性值需要添加&#xff0c;也可能老旧的设计图纸需要统一规范。 这时我们用SOLIDWORKS自带的属性标签工具就可以快速完成文件的属性编辑。 1打开工程图纸&#xff0c;…