当前位置: 首页 > news >正文

C++:优先级队列

目录

1. 概念

2. 特征

3. 优先级队列的使用


1. 概念

优先级队列虽然名字有队列二字,但根据队列特性来说优先级队列不满足先进先出这个特征,优先级队列的底层是用堆来实现的。

优先级队列是一种容器适配器,就是将特定容器类封装作为其底层容器类

2. 特征

这是优先级队列的模板参数,第一个是具体元素的类型,第二个是实现底层连接的容器,默认是vector,第三个则是改变优先级的参数了,这里默认是仿函数less。对于此处仿函数的使用可以参考下面的文章 :C++:仿函数-CSDN博客

这里特定容器的选择需满足以下条件:

empty():检测容器是否为空
size():返回容器中有效元素个数
front():返回容器中第一个元素的引用
push_back():在容器尾部插入元素
pop_back():删除容器尾部元素

以及改容器可以通过随机访问迭代器访问,因为建堆是需要通过子节点找到父节点或通过父节点找子节点。

综合以上条件,有vector和deque满足。

注意:priority_queue包含在queue的头文件中。

3. 优先级队列的使用

优先级队列默认使用vector作为其底层存储数据的容器,在vector上又使用了堆算法将vector中元素构造成 堆的结构,因此priority_queue就是堆,所有需要用到堆的位置,都可以考虑使用priority_queue。
常用参数作用
empty()判断是否为空
size()优先级队列的长度
push()向队尾插入数据
pop()删除顶部数据
swap()交换两个数据
top()
返回优先级队列中最大(最小元素),即堆顶元素

下面的代码中当我们只写一个参数时,后两个模板参数默认为vector和less(大堆)

int main()
{int num[] = { 3,5,7,1,9,4 };priority_queue<int> pq(num, num + sizeof(num) / sizeof(int));while (!pq.empty()){cout << pq.top() << " ";pq.pop();}cout << endl;
}

我们每次删除或插入数据后,都会将优先级队列重新建堆,保证优先级最高的元素始终在顶部。

注意:如果priority_queue中放的是自定义类型,那需要我们先写出这个自定义类型的 < 和 > 的重载函数。

如果优先级队列中放的是一个开辟空间的节点,那么就必须自己写一个仿函数

下面代码中用的是库函数中的仿函数,那么此时因为仿函数中比较的的是指针,也就是空间的大小,而每次开辟的空间大小都是随机的,所以我们每次运行的结果都是不同的;

这里Less是模拟库函数中的less

template<class T>
class Less
{
public:bool operator()(const T& a, const T& b){return a < b;}
};
int main()
{priority_queue<Date*, vector<Date*>, Less<Date*> > pq;pq.push(new Date(2004, 7, 10));pq.push(new Date(2004, 6, 10));pq.push(new Date(2004, 8, 10));while (!pq.empty()){cout << *pq.top() << " ";pq.pop();}cout << endl;
}

解决的办法就是我们手动写一个专属于Date类的仿函数LessDate,返回解引用的比较,此时比较的就是实际的数了。

class LessDate
{
public:bool operator()(const Date* a, const Date* b){return *a < *b;}
};
int main()
{priority_queue<Date*, vector<Date*>,LessDate > pq;pq.push(new Date(2004, 7, 10));pq.push(new Date(2004, 6, 10));pq.push(new Date(2004, 8, 10));while (!pq.empty()){cout << *pq.top() << " ";pq.pop();}cout << endl;
}

http://www.lqws.cn/news/103951.html

相关文章:

  • SOC-ESP32S3部分:28-BLE低功耗蓝牙
  • 【数学】高斯积分+伽马函数公式自用背诵笔记
  • Rust 学习笔记:Cargo 工作区
  • CppCon 2014 学习:Rolling Your Own Circuit Simulator
  • 应用智能化转型—MCP原理分析
  • 帝可得 - 策略管理
  • 【MATLAB去噪算法】基于CEEMD联合小波阈值去噪算法(第三期)
  • c++基础(三)
  • Trae CN IDE自动生成注释功能测试与效率提升全解析
  • Linux: network : switch:hp5500
  • 情趣私域运营:打造高效转化的私域营销体系
  • 【Redis】笔记|第7节|大厂生产级Redis高并发分布式锁实战(二)
  • 第11节 Node.js 模块系统
  • WebRTC中sdp多媒体会话协议报文详细解读
  • 法律大语言模型(Legal LLM)技术架构
  • Selenium 中 JavaScript 点击操作的原理及应用
  • Nginx+Tomcat 负载均衡、动静分离
  • 设计模式-原型模式
  • Java面试八股--08-数据结构和算法篇
  • 0518蚂蚁暑期实习上机考试题1:数组操作
  • go get下载三方库异常
  • STM32入门教程——按键控制LED光敏传感器控制蜂鸣器
  • Leetcode 261. 以图判树
  • ​链表题解——回文链表【LeetCode】
  • Java基础 Day28 完结篇
  • 使用 Golang `testing/quick` 包进行高效随机测试的实战指南
  • Elasticsearch集群最大分片数设置详解:从问题到解决方案
  • Mac电脑_钥匙串操作选项变灰的情况下如何删除?
  • React-native之Flexbox
  • 相机Camera日志分析之二十四:高通相机Camx 基于预览1帧的process_capture_request三级日志分析详解