STL容器适配器 -- priority_queue(使用+实现)(C++)

priority_queue

  • priority_queue 简单介绍
  • priority_queue 使用
    • 内置类型测试
    • 自定义类型测试
  • priority_queue 模拟实现
  • 仿函数(less、greater)

priority_queue 简单介绍

优先级队列是一种容器适配器。类似于堆,可以随时插入元素,只能检索优先级队列中位于顶部的元素。

priority_queue是作为容器适配器实现的,容器适配器是对特定容器类封装,作为其底层的容器。vector、deque符合priority_queue需求,如果没有指定特定的底层容器,默认使用vector。需要支持随机访问迭代器,以便内部保持堆结构。

priority_queue 使用

在默认底层容器vector中使用堆算法,将vector中的元素构成堆的结构,所以priority_queue就是堆
使用场景:在需要用到堆的位置。priority_queue默认是大堆。

函数接口说明
priority_queue()构造空的优先级队列
priority_queue(first, last)迭代器范围构造优先级队列
empty()判断优先级队列是否为空
top()返回堆顶元素的const引用
push(val)将val插入优先级队列中
pop()删除堆顶元素

内置类型测试

void test_priority_queue()
{//默认是大堆 -- less   less在sort中对应的是升序,但是在priority_queue中建的大堆//priority_queue<int> pq;//仿函数greater控制建小堆priority_queue<int, vector<int>, greater<int>> pq;pq.push(5);pq.push(10);pq.push(3);pq.push(1);while (!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;
}

test2:

void test_priority_queue()
{vector<int> v{ 3,2,7,6,0,4,1,9,8,5 };//默认大堆priority_queue<int> pq;for (auto& e : v){pq.push(e);}cout << pq.top() << endl;//创建小堆priority_queue<int, vector<int>, greater<int>> pq1(v.begin(), v.end());cout << pq1.top() << endl;
}

自定义类型测试

如果是自定义类型的数据,用户需要提供大于(>)或者小于(<)的重载

class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);public:Date(int year = 1900, int month = 1, int day = 1):_year(year),_month(month),_day(day){}bool operator<(const Date& d)const{return (_year < d._year) ||(_year == d._year && _month < d._month) ||(_year == d._year && _month == d._month && _day < d._day);}bool operator>(const Date& d)const{return (_year > d._year) ||(_year == d._year && _month > d._month) ||(_year == d._year && _month == d._month && _day > d._day);}private:int _year;int _month;int _day;
};ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << "-" << d._month << "-" << d._day;return _cout;
}void test_priority_queue()
{// 大堆,需要用户在自定义类型中提供<的重载priority_queue<Date> pq1;pq1.push(Date(2023, 8, 6));pq1.push(Date(2023, 7, 6));pq1.push(Date(2023, 6, 6));cout << pq1.top() << endl;// 如果要创建小堆,需要用户提供>的重载priority_queue<Date, vector<Date>, greater<Date>> pq2;pq2.push(Date(2023, 8, 6));pq2.push(Date(2023, 7, 6));pq2.push(Date(2023, 6, 6));cout << pq2.top() << endl;
}

注意: 如果自定义类型没有重载用于比较的符号, 则程序运行错误。

priority_queue 模拟实现

priority_queue类模板实现,借用了一个容器vector和两个仿函数less、greater。如果想进一步观察priority_queue的逻辑结构,请点击该链接:堆的实现

#include <vector>
#include <assert.h>// priority_queue--->堆
namespace kpl
{template<class T>struct less{bool operator()(const T& left, const T& right){return left < right;}};template<class T>struct greater{bool operator()(const T& left, const T& right){return left > right;}};template<class T, class Container = std::vector<T>, class Compare = less<T>>class priority_queue{public:// 创造空的优先级队列priority_queue(){}/*template<class InputIterator>priority_queue(InputIterator first, InputIterator last){	//这里可以不使用初始化列表//数据存入while (first != last){_con.push_back(*first);++first;}//向下调整建堆for (size_t i = (_con.size() - 1 - 1) / 2; i >= 0; --i){AdjustDown(i);}}*/template<class InputIterator>priority_queue(InputIterator first, InputIterator last): _con(first, last){// 将_con中的元素调整成堆的结构//向下调整建堆for (size_t i = (_con.size() - 1 - 1) / 2; i >= 0; --i){AdjustDown(i);}}void push(const T& data){_con.push_back(data);AdjustUP(_con.size() - 1);}void pop(){assert(!_con.empty());swap(_con.front(), _con.back());_con.pop_back();AdjustDown(0);}size_t size()const{return _con.size();}bool empty()const{return _con.empty();}// 堆顶元素不允许修改,因为:堆顶元素修改可以会破坏堆的特性const T& top()const{return _con.front();}private:// 向上调整void AdjustUP(int child){int parent = (child - 1) / 2;while (child){if (_com(_con[parent], _con[child])){swap(_con[child], _con[parent]);child = parent;parent = (child - 1) / 2;}else{break;}}}// 向下调整void AdjustDown(int parent){size_t child = parent * 2 + 1;while (child < _con.size()){// 找以parent为根的较大的孩子if (child + 1 < _con.size() && _com(_con[child], _con[child + 1]))child += 1;// 检测双亲是否满足情况if (_com(_con[parent], _con[child])){swap(_con[child], _con[parent]);parent = child;child = parent * 2 + 1;}else{break;}}}private:Container _con;Compare _com;};
}

仿函数(less、greater)

仿函数(functor)是一个能行使函数功能的类或结构体。它实际上是一个可调用的对象,可以像调用函数一样来使用它,传入参数并获得返回值。与普通函数不同的是,仿函数可以保存状态信息,并且可以被其他函数调用。为了成为一个仿函数,类或结构体必须重载 operator() 运算符。在C++中,仿函数通常用于STL算法中的自定义排序、查找、过滤等操作。

test1:

//仿函数/函数对象
template<class T>
struct less
{bool operator()(const T& left, const T& right){return left < right;}
};template<class T>
struct greater
{bool operator()(const T& left, const T& right){return left > right;}
};int main()
{less<int> lessFunc;cout << lessFunc(1, 2) << endl;cout << lessFunc.operator()(1, 2) << endl;cout << less<int>()(1, 2) << endl;
}

test2: 仿函数的匿名对象使用

int main()
{greater<int> g;vector<int> v{ 1,3,4,1,0 };sort(v.begin(), v.end(), g);//sort(v.begin(), v.end(), greater<int>());//greater<int>() --> 匿名对象for (auto e : v){cout << e << " ";}cout << endl;cout << greater<int>()(1, 2) << endl;cout << g(1, 2) << endl;
}

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

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

相关文章

Docker环境下MySQL备份恢复工具XtraBackup使用详解 | Spring Cloud 62

一、XtraBackup 简介 Percona XtraBackup是一个开源的MySQL和MariaDB数据库备份工具&#xff0c;它能够创建高性能、一致性的备份&#xff0c;并且对生产环境的影响很小。Percona XtraBackup通过在不停止MySQL服务器的情况下&#xff0c;复制InnoDB存储引擎的数据文件和事务日…

应用Numpy实现对数据的处理

创建简单的数组 主要使用np.array()函数&#xff0c;语法如下 import numpy as np np.array(object,dtypeNone,copyTrue,orderK,subokFalse,ndmin0) 主要参数&#xff1a; Object&#xff1a;任何具有数组接口方法的对象 dtype&#xff1a;数据类型 ndmin:指定生成数组的最…

Apache Thrift C++库的TThreadPoolServer模式的完整示例

1. 本程序功能 1) 要有完整的request 和 response; 2) 支持多进程并行处理任务&#xff1b; 3)子进程任务结束后无僵尸进程 2.Apache Thrift C库的编译和安装 见 步步详解&#xff1a;Apache Thrift C库从编译到工作模式DEMO_北雨南萍的博客-CSDN博客 3.框架生成 数据字…

简述静态网页和动态网页的区别。简述 Webl.0 和 Web2.0 的区别。安装tomcat8,配置服务启动脚本,部署jpress应用

静态网页和动态网页区别 静态网页和动态网页是两种常见的网页类型&#xff0c;它们在内容生成和交互方式上存在不同。 静态网页是在服务器上提前生成好的网页&#xff0c;它的内容在访问时不会发生变化。静态网页通常由HTML、CSS和JavaScript等静态文件组成&#xff0c;这些文…

【css问题】flex布局中,子标签宽度超出父标签宽度,导致布局出现问题

场景&#xff1a;文章标题过长时&#xff0c;只显示一行&#xff0c;且多余的部分用省略号显示。 最终效果图&#xff1a; 实现时&#xff0c;flex布局&#xff0c;出现问题&#xff1a; 发现text-overflow: ellipsis不生效&#xff0c;省略符根本没有出现。 而且因为设置了 …

《MySQL高级篇》十五、其他数据库日志

文章目录 1. MySQL支持的日志1.1 日志类型1.2 日志的弊端 2. 慢查询日志(slow query log)3. 通用查询日志3.1 问题场景3.2 查看当前状态3.3 启动日志3.4 查看日志3.5 停止日志3.6 删除\刷新日志 4. 错误日志(error log)4.1 启动日志4.2 查看日志4.3 删除\刷新日志4.4 MySQL8.0新…

ThreadLocal有内存泄漏问题吗

对于ThreadLocal的原理不了解或者连Java中的引用类型都不了解的可以看一下我的之前的一篇文章Java中的引用和ThreadLocal_鱼跃鹰飞的博客-CSDN博客 我这里也简单总结一下: 1. 每个Thread里都存储着一个成员变量&#xff0c;ThreadLocalMap 2. ThreadLocal本身不存储数据&…

flutter开发实战-实现首页分类目录入口切换功能

。 在开发中经常遇到首页的分类入口&#xff0c;如美团的美食团购、打车等入口&#xff0c;左右切换还可以分页更多展示。 一、使用flutter_swiper_null_safety 在pubspec.yaml引入 # 轮播图flutter_swiper_null_safety: ^1.0.2二、实现swiper分页代码 由于我这里按照一页8…

装饰器模式(C++)

定义 动态(组合)地给一个对象增加一些额外的职责。就增加功能而言&#xff0c;Decorator模式比生成子类(继承)更为灵活(消除重复代码&减少子类个数)。 一《设计模式》 GoF 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xf…

[openCV]基于拟合中线的智能车巡线方案V2

import cv2 as cv import os import numpy as np# 遍历文件夹函数 def getFileList(dir, Filelist, extNone):"""获取文件夹及其子文件夹中文件列表输入 dir&#xff1a;文件夹根目录输入 ext: 扩展名返回&#xff1a; 文件路径列表"""newDir d…

【JavaScript】元素获取指南

简介 在 JavaScript 中,我们经常需要通过获取元素来进行 DOM 操作和交互。本教程将介绍多种获取元素的方式,包括根据 ID、标签名、类名、选择器、属性和名称等。 通过ID获取元素 使用getElementById方法根据元素的ID属性获取单个元素。 var element = document.getElementB…

机器学习框架PyTorch详解和案列分析

目录 一、基本介绍二、基本概念三、操作流程四、详细安装命令五、应用场景六、最新发展 PyTorch 是一个基于 Python 的科学计算包&#xff0c;主要针对两类人群&#xff1a; 作为 NumPy 的替代品&#xff0c;可以利用 GPU 的性能进行计算。作为一个高灵活性、速度快的深度学习平…

【windows】powershell使用ll、head、tail等linux命令

powershell使用ll、head、tail等linux命令 最近在windows系统上办公比较多&#xff0c;想使用linux上经常用到的ll、head、tail等命令。发现可以通过修改powershell的配置文件来实现。具体地&#xff0c;一般需要修改以下路径的配置文件&#xff0c;没有的话就在该路径下创建一…

Unity学习参考文档和开发工具

☺ unity的官网文档&#xff1a;脚本 - Unity 手册 ■ 学习方式&#xff1a; 首先了解unity相关概述&#xff0c;快速认识unity编辑器&#xff0c;然后抓住重点的学&#xff1a;游戏对象、组件|C#脚本、预制体、UI ☺ 学习过程你会发现&#xff0c;其实Unity中主要是用c#进行开…

[Docker实现测试部署CI/CD----自由风格和流水线的CD操作(6)]

目录 12、自由风格的CD操作发布 V1.0.0 版本修改代码并推送GitLab 中项目打 Tag 发布 V2.0.0 版本Jenkins 配置 tag 参数添加 Git 参数添加 checkout 命令修改构建命令配置修改 SSH 配置 部署 v1.0.0重新构建工程构建结果 部署 v2.0.0重新构建工程访问 部署v3.0.0 13、流水线任…

Jmeter函数助手(一)随机字符串(RandomString)

一、目标 实现一个请求单次调用&#xff0c;请求体里多个集合中的相同参数&#xff08;zxqs&#xff09;值随机从序列{01、02、03、03、04、05、06、07、08}中取 若使用CSV数据文件、用户参数等参数化手段&#xff0c;单次执行请求&#xff0c;请求体里多个集合中的相同参数&a…

传染病学模型 | Python实现基于使用受控SIR模型分析SARS-CoV-2疫情

效果一览 文章概述 传染病学模型 | Python实现基于使用受控 SIR 模型分析 SARS-CoV-2 疫情 源码设计 import jax.numpy as np import

webpack基础知识七:说说webpack proxy工作原理?为什么能解决跨域?

一、是什么 webpack proxy&#xff0c;即webpack提供的代理服务 基本行为就是接收客户端发送的请求后转发给其他服务器 其目的是为了便于开发者在开发模式下解决跨域问题&#xff08;浏览器安全策略限制&#xff09; 想要实现代理首先需要一个中间服务器&#xff0c;webpac…

Python 开发工具 Pycharm —— 使用技巧Lv.2

pydoc是python自带的一个文档生成工具&#xff0c;使用pydoc可以很方便的查看类和方法结构 本文主要介绍&#xff1a;1.查看文档的方法、2.html文档说明、3.注释方法、 一、查看文档的方法 **方法1&#xff1a;**启动本地服务&#xff0c;在web上查看文档 命令【python3 -m…

基于STM32CubeMX和keil采用通用定时器中断实现固定PWM可调PWM波输出分别实现LED闪烁与呼吸灯

文章目录 前言1. PWM波阐述2. 通用定时器2.1 为什么用TIM142.2 TIM14功能介绍2.3 一些配置参数解释2.4 PWM实现流程&中断2.4.1 非中断PWM输出(LED闪烁)2.4.2 中断PWM输出(LED呼吸灯) 3. STM32CubeMX配置3.1 GPIO配置3.2 时钟配置3.3 定时器相关参数配置3.4 Debug配置3.5 中…