STL —— priority_queue

图片名称

博主首页: 有趣的中国人
 

专栏首页: C++专栏
 


 

本篇文章主要讲解 priority_queue 的相关内容

目录

1. 优先级队列简介

基本操作

 2. 模拟实现

2.1 入队操作

2.2 出队操作

2.3 访问队列顶部元素

2.4 判断优先队列是否为空

2.5 获取优先队列的大小

3. 仿函数

仿函数的特点

使用场景

示例代码

仿函数替代函数指针

4.利用仿函数实现优先级队列 

5. 有关自定义类型的排序


 

1. 优先级队列简介

std::priority_queue 是一个模板类,定义在 <queue> 头文件中,它基于堆(heap)数据结构来实现优先队列的功能。默认情况下,std::priority_queue 使用 std::vector 作为其底层容器,并且使用比较器(默认是 std::less)来决定元素的优先级顺序。 

基本操作

  1. 入队操作: 使用 push() 成员函数将元素推入优先队列中。

    std::priority_queue<int> myPriorityQueue;
    myPriorityQueue.push(10);
  2. 出队操作: 使用 pop() 成员函数从优先队列中移除顶部(优先级最高)的元素。

    myPriorityQueue.pop();
    
  3. 访问队列顶部元素: 使用 top() 成员函数获取优先队列顶部(优先级最高)的元素,但不会将其从队列中移除。

    int topElement = myPriorityQueue.top();
    
  4. 判断优先队列是否为空: 使用 empty() 成员函数检查优先队列是否为空。

    if (!myPriorityQueue.empty()) {// 优先队列不为空
    }
    
  5. 获取优先队列的大小: 使用 size() 成员函数获取优先队列中元素的数量。

    int queueSize = myPriorityQueue.size();
    

 2. 模拟实现

其模拟实现的方式也是按照容器适配器的模式来完成的,刚才提到过其底层是堆的形式,那么只需要用vector来模拟实现即可

2.1 入队操作

void adjust_up()
{int child = _con.size() - 1;int parent = (child - 1) / 2;while (child > 0){if (_con[parent] < _con[child]){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}
}
// 大堆
void push(const T& val)
{_con.push_back(val);adjust_up();
}

2.2 出队操作

void adjust_down()
{int parent = 0;int child = (parent * 2) + 1;while (child < _con.size()){if (child + 1 < size() && (_con[child] < _con[child + 1])){++child;}if (_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();
}

2.3 访问队列顶部元素

T& top()
{return _con.front();
}

2.4 判断优先队列是否为空

bool empty()
{return _con.empty();
}

2.5 获取优先队列的大小

size_t size()
{return _con.size();
}

3. 仿函数

仿函数是C++中的一个概念,它实际上是一个类或结构体,但其行为类似于函数。仿函数可以像函数一样被调用,因此也被称为函数对象。

仿函数的特点

  1. 类似函数: 仿函数实际上是一个类对象,但其重载了函数调用运算符 operator(),使得它可以像函数一样被调用。

  2. 灵活性: 仿函数可以包含状态,因此可以捕获和存储额外的信息,而这在普通函数中可能很难实现。

  3. 可定制性: 仿函数可以根据需要进行定制,比如可以重载不同的函数调用运算符,或者添加额外的成员函数。

使用场景

  1. 作为函数对象传递: 仿函数可以作为参数传递给算法函数,这在STL中非常常见。比如,std::sort 函数可以接受一个仿函数来定义排序的顺序。

  2. 定制排序规则: 当需要对容器中的元素进行排序时,可以使用仿函数来定义排序规则,比如按照自定义的比较方式排序。

  3. 条件判断: 仿函数可以用于条件判断,例如在算法中过滤元素时。

示例代码

下面是一个简单的示例,演示了如何定义和使用一个简单的仿函数:

#include <iostream>// 定义一个简单的仿函数
struct MyFunctor {void operator()(int x) const {std::cout << "Value: " << x << std::endl;}
};int main() {MyFunctor myFunc;// 调用仿函数myFunc(10);return 0;
}

仿函数替代函数指针

在许多情况下,仿函数可以替代函数指针,并提供更多的灵活性和可扩展性。 

我们知道在C语言中的qsort中,只需要给出两个元素的比较大小的方式,就可以传递函数指针来进行大小的排序,然而在C++中,我们可以传递仿函数,并调用算法库中的sort来进行排序,例如以下的代码:

#include <iostream>
#include <vector>
#include <algorithm>// 定义一个比较器仿函数
struct MyComparator 
{bool operator()(int a, int b) const {return a % 10 < b % 10; // 按照个位数进行排序}
};int main() 
{std::vector<int> nums = {15, 30, 25, 12, 7};// 使用仿函数进行排序// 传匿名对象std::sort(nums.begin(), nums.end(), MyComparator());// 打印排序后的结果for (int num : nums) {std::cout << num << " ";}std::cout << std::endl;return 0;
}


4.利用仿函数实现优先级队列 

按照这样的逻辑,我们就可以用仿函数来实现优先级队列,

  • 如果按照升序排序,建小堆,传greater比较方式;
  • 如果按照降序排序,建大堆,传less比较方式。
template<class T>
class less
{
public:bool operator()(const T& left, const T& right){return left < right;}
};template<class T>
class greater
{
public:bool operator()(const T& left, const T& right){return left > right;}
};template<class T, class Container = vector<T>, class Compare = greater<T>>
class priority_queue
{
public:void adjust_up(){Compare com;int child = _con.size() - 1;int parent = (child - 1) / 2;while (child > 0){if (com(_con[parent], _con[child])){swap(_con[parent], _con[child]);child = parent;parent = (child - 1) / 2;}else{break;}}}// 大堆void push(const T& val){_con.push_back(val);adjust_up();}void adjust_down(){Compare com;int parent = 0;int child = (parent * 2) + 1;while (child < _con.size()){if (child + 1 < size() && com(_con[child], _con[child + 1])){++child;}if (com(_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();}T& top(){return _con.front();}bool empty(){return _con.empty();}size_t size(){return _con.size();}private:Container _con;
};

5. 有关自定义类型的排序

在很多情况下,我们需要对一个自定义类型按照某种形式进行排序,例如,对于一种商品,可能对他的评价、价格、销量等情况进行排序,这个时候我们就可以运用仿函数了。

struct Goods
{string _name; // 名字double _price; // 价格int _evaluate; // 评价Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){}
};struct compare_price_less
{bool operator()(const Goods& gdp1, const Goods& gdp2){return gdp1._price < gdp2._price;}
};struct compare_evaluate_less
{bool operator()(const Goods& gde1, const Goods& gde2){return gde1._evaluate < gde2._evaluate;}
};struct compare_name_greater
{bool operator()(const Goods& gdn1, const Goods& gdn2){return gdn1._name > gdn2._name;}
};int main()
{vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2,3 }, { "菠萝", 1.5, 4 } };sort(v.begin(), v.end(), compare_name_greater());sort(v.begin(), v.end(), compare_evaluate_less());sort(v.begin(), v.end(), compare_price_less());return 0;
}

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

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

相关文章

什么是One-Class SVM

1. 简介 单类支持向量机&#xff0c;简称One-Class SVM(One-Class Support Vector Machine)&#xff0c;用于异常检测和离群点检测(无监督学习&#xff0c;其他svm属于有监督的)&#xff0c;可以在没有大量异常样本的情况下有效地检测异常。其目标是通过仅使用正常数据来建模&a…

【力扣 Hot100 | 第四天】4.15(括号生成)

文章目录 4.括号生成4.1题目4.2解法&#xff1a;回溯4.2.1回溯思路&#xff08;1&#xff09;函数返回值以及参数&#xff08;2&#xff09;终止条件&#xff08;3&#xff09;遍历过程 4.2.2代码 4.括号生成 4.1题目 数字 n 代表生成括号的对数&#xff0c;请你设计一个函数…

三斜求积术 To 海伦公式 ← 三角形面积

【知识点&#xff1a;三斜求积术】 所谓秦九韶的三斜求积术&#xff0c;即如果已知三角形的边长a&#xff0c;b&#xff0c;c&#xff0c;可求得该三角形的面积为&#xff1a; 而由三斜求积术可推得海伦公式。过程如下&#xff1a; 其中&#xff0c; 上面推导公式的 Latex 代码…

​​​​网络编程探索系列之——广播原理剖析

hello &#xff01;大家好呀&#xff01; 欢迎大家来到我的网络编程系列之广播原理剖析&#xff0c;在这篇文章中&#xff0c; 你将会学习到如何在网络编程中利用广播来与局域网内加入某个特定广播组的主机&#xff01; 希望这篇文章能对你有所帮助&#xff0c;大家要是觉得我写…

从零开始写 Docker(十一)---实现 mydocker exec 进入容器内部

本文为从零开始写 Docker 系列第十一篇&#xff0c;实现类似 docker exec 的功能&#xff0c;使得我们能够进入到指定容器内部。 完整代码见&#xff1a;https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实现有一个大致认识&#xff1a; 核心原理&…

「51媒体」如何有效进行媒体邀约,提升宣传传播效果?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 进行有效的媒体邀约&#xff0c;提升宣传传播效果的关键在于策略性和专业性。以下是具体的做法&#xff1a; 明确目标&#xff1a;要确立清晰的品牌推广目标和策略&#xff0c;包括确定目…

软考-系统集成项目管理中级--范围管理(输入输出很重要!!!)

本章历年考题分值统计 本章重点常考知识点汇总清单(掌握部分可直接理解记忆) 12、标杆对照将实际或计划的做法(如流程和操作过程)与其他可比组织的做法进行比较&#xff0c;以便识别最佳实践&#xff0c;形成改进意见&#xff0c;并为绩效考核提供依据。标杆对照所采用的可比组…

【YOLOv8改进[损失函数]】使用结合InnerIoU和Focaler的各种损失函数助力YOLOv8更优秀

目录 一 回归损失函数&#xff08;Bounding Box Regression Loss&#xff09; 1 Inner-IoU 2 Focaler-IoU&#xff1a;更聚焦的IoU损失 二 改进YOLOv8的损失函数 1 总体修改 ① ultralytics/utils/metrics.py文件 ② ultralytics/utils/loss.py文件 ③ ultralytics/uti…

亚马逊云科技直冲云霄训练营活动开始啦(送考试半价券)

小李哥分享的是亚马逊科技官方免费直冲云霄训练营学习活动&#xff0c;通过该活动可以薅到以下的羊毛 1️⃣免费系统性技能培训&#xff0c;成为AWS技术大牛 2️⃣考试半价券&#xff0c;最高可省1086元人民币 3️⃣分享活动获得精美礼品 4️⃣亚马逊云科技年度全球技术大会门票…

什么是T型槽铸铁平板中内应力——河北北重厂家

T型槽铸铁平板中的内应力指的是平板内部受到的内部力&#xff0c;包括拉应力和剪应力。在T型槽铸铁平板使用过程中&#xff0c;由于自身重量、外力加载等原因&#xff0c;会产生内部应力。这些内应力是平板内部各部分之间的相互作用力&#xff0c;使得平板各部分受到不同的拉伸…

FreeSWITCH 1.10.10 简单图形化界面1 - docker/脚本/ISO镜像安装[YouCanSee]

FreeSWITCH 1.10.10 简单图形化界面1 - docker/脚本/ISO镜像安装 0. 界面预览00. 使用手册在这里1. Docker安装1.1 下载docker镜像1.2 启动docker镜像1.3 登录 2. 脚本安装2.1 下载2.2 安装2.3 登录2.4 卸载程序 3. 镜像安装3.1 下载镜像3.2 安装镜像3.3 登录 0. 界面预览 网站…

基于SpringBoot+Vue的在线教育系统(源码+文档+包运行)

一.系统概述 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了在线教育系统的开发全过程。通过分析在线教育系统管理的不足&#xff0c;创建了一个计算机管理在线教育系统的方案。文章介绍了在线教育系统的系统分析部…

ETL工具-nifi干货系列 第十三讲 nifi处理器QueryDatabaseTable查询表数据实战教程

1、处理器QueryDatabaseTable&#xff0c;该组件生成一个 SQL 查询&#xff0c;或者使用用户提供的语句&#xff0c;并执行它以获取所有在指定的最大值列中值大于先前所见最大值的行。查询结果将被转换为 Avro 格式&#xff0c;如下图所示&#xff1a; 本示例通过QueryDatabase…

【模板】差分

本题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例&#xff1a; 输入 3 2 1 2 3 1 2 4 3 3 -2 输出 5 6 1 思路&#xff1a; 一直以来&#xff0c;我总是不太理解差分和树状数组操作区别。 现在摸了一下开始有所理解了。 差分和树状数组的区别…

硬件开源--Model 3C(简称M3)芯片驱动RGB接口86中控屏PCBA原理图

针对市场IOT应用需求&#xff0c;基于启明智显的Model3C芯片(简称M3)设计开发的一款超高性价比的86型中控屏PCBA原理图开源。 Model3C芯片(简称M3)是一款基于 RISC-V 的高性能、国产自主、工业级高清显示与智能控制 MCU&#xff0c;配备强大的 2D 图形加速处理器、PNG/JPEG 解码…

LeetCode 202. 快乐数

LeetCode 202. 快乐数 1、题目 力扣题目链接&#xff1a;202. 快乐数 编写一个算法来判断一个数 n 是不是快乐数。 「快乐数」 定义为&#xff1a; 对于一个正整数&#xff0c;每一次将该数替换为它每个位置上的数字的平方和。然后重复这个过程直到这个数变为 1&#xff0c;…

关于 Windows10 计算机丢失 MSVCP120.dll 的解决方法

今天学长跟平时一样打开电脑开始发布文章需要用到Adobe Photoshop CC 2018的时候居然给我来个Photoshop.exe-系统错误、无法启动此程序&#xff0c;因为计算机中丢失MSVCP120.dll 尝试重新安装该程序以解决此问题&#xff0c;安装上面的说明重新安装了我的Photoshop CC 打开还是…

财务数字化转型如何找到打通业财融合的关键点

随着企业信息联网核查系统上线及即将到来的金税四期&#xff0c;企业将面临全业务、全方位、全流程的监控&#xff0c;企业“合不合规、经不经得起核查”&#xff0c;成为企业经营的一个重大考题。在此大环境下&#xff0c;财税安全成为企业经营中重要一环&#xff0c;尤为突出…

算法打卡day46|动态规划篇14| Leetcode 1143.最长公共子序列、1035.不相交的线、53. 最大子序和

算法题 Leetcode 1143.最长公共子序列 题目链接:1143.最长公共子序列 大佬视频讲解&#xff1a;1143.最长公共子序列视频讲解 个人思路 本题和718. 最长重复子数组很相像&#xff0c;思路差不多还是用动态规划。区别在于这题不要求是连续的了&#xff0c;但要有相对顺序 解…

PHP婚恋小程序开发源码支持微信+公众号+APP

随着社会的发展和人们生活节奏的加快&#xff0c;传统的相亲方式已经不能满足现代人的需求。在此背景下&#xff0c;有人想到通过线上小程序的方式来满足更多的人进行相亲&#xff0c;所以在此情况下&#xff0c;婚恋相亲小程序由此出现。婚恋相亲小程序的功能有会员功能&#…