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

45 C++ STL模板库14-容器6-容器适配器-优先队列(priority_queue)

STL模板库-容器6-容器适配器-优先队列(priority_queue)

文章目录

  • STL模板库-容器6-容器适配器-优先队列(priority_queue)
    • 1. 成员类型
    • 2. 构造函数
    • 3. 核心成员函数
      • (1). 容量操作
      • (2). 元素访问
      • (3). 修改操作
      • (4). 交换操作
    • 4. 非成员函数
    • 5. 底层容器与比较器
    • 6. 关键特性与注意事项
    • 7. 完整示例

priority_queue 是一个容器适配器,默认基于 std::vector 实现,元素按优先级(默认最大堆)排序,定义在 <queue> 头文件中。
priority_queue 提供了高效的动态优先级管理,核心操作围绕堆顶元素展开,适合需要频繁插入和删除最高/最低优先级元素的场景。通过自定义容器和比较器,可灵活适配不同需求。

1. 成员类型

类型名称描述
value_type元素类型(模板参数 T
container_type底层容器类型(默认 vector<T>
size_type表示大小的无符号整数(如 size_t
reference元素的引用(如 T&
const_reference元素的常量引用(如 const T&

2. 构造函数

构造函数签名说明
priority_queue()默认构造空队列
explicit priority_queue(const Compare& comp)指定比较器(如 std::greater<T>
priority_queue(const Compare& comp, Container&& c)用底层容器初始化(可移动或拷贝)
template <class InputIt> priority_queue(InputIt first, InputIt last, ...)通过迭代器范围构造

3. 核心成员函数

(1). 容量操作

函数签名功能描述时间复杂度
bool empty() const检查队列是否为空O(1)
size_type size() const返回元素数量O(1)

(2). 元素访问

函数签名功能描述时间复杂度
const_reference top() const返回堆顶元素(最高优先级)O(1)

(3). 修改操作

函数签名功能描述时间复杂度
void push(const T& value)插入元素(拷贝语义)O(log n)
void push(T&& value)插入元素(移动语义,C++11起)O(log n)
template <class... Args> void emplace(Args&&... args)直接构造元素(避免拷贝)O(log n)
void pop()移除堆顶元素O(log n)

(4). 交换操作

函数签名功能描述时间复杂度
void swap(priority_queue& other) noexcept交换两个队列内容(C++11起)O(1)

4. 非成员函数

函数签名说明
void swap(priority_queue<T>& a, priority_queue<T>& b)全局交换函数(同成员函数)

5. 底层容器与比较器

  • 底层容器要求:
    必须支持 front(), push_back(), pop_back() 和随机访问迭代器(如 vectordeque)。

  • 自定义比较器:

    // 示例:最小堆(优先级小的先出队)
    priority_queue<int, vector<int>, greater<int>> minHeap;
    

6. 关键特性与注意事项

  1. 无迭代器:无法直接遍历元素,只能通过 top()pop() 遍历元素(会清空队列)

  2. 性能特点:插入和删除操作的时间复杂度为 O(log n),堆顶访问为 O(1)。

  3. 默认行为:最大堆(std::less<T> 比较器)。

  4. 底层容器:默认 vector,可替换为 deque(需支持随机访问和 pop_back

  5. 比较器规则:返回 true 表示 左参数优先级更低

    // 自定义比较函数示例
    auto cmp = [](int a, int b) { return a > b; };
    std::priority_queue<int, std::vector<int>, decltype(cmp)> customHeap(cmp);
    
  6. 适用场景:任务调度、Dijkstra算法、Top K问题等需要动态排序的场景。

7. 完整示例

#include <iostream>
#include <queue>
#include <vector>
#include <functional> // std::greater int main() {// ===== 1. 基础用法(默认最大堆)=====std::priority_queue<int> maxHeap; // 默认:大值优先maxHeap.push(30); maxHeap.push(10); maxHeap.emplace(50);  // 直接构造元素std::cout << "最大堆顶部: " << maxHeap.top()  << "\n"; // 50 // ===== 2. 自定义排序规则 =====// 最小堆(小值优先)std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;minHeap.push(30); minHeap.push(10); std::cout << "最小堆顶部: " << minHeap.top()  << "\n\n"; // 10 // ===== 3. 使用自定义容器初始化 ===== std::vector<int> nums{15, 25, 5};std::priority_queue<int> q(nums.begin(),  nums.end()); std::cout << "容器初始化堆顶: " << q.top()  << "\n"; // 25// ===== 4. 完整操作示例 ===== std::priority_queue<std::string> tasks;// 添加元素tasks.push(" 写报告");tasks.emplace(" 调试代码"); tasks.push(" 会议准备");// 容量查询 std::cout << "\n任务数量: " << tasks.size();  // 3std::cout << "\n是否为空: " << (tasks.empty()  ? "是" : "否") << "\n\n"; // 否// 访问并移除元素(按字典序降序)std::cout << "任务处理顺序:\n";while (!tasks.empty())  {std::cout << "正在处理: " << tasks.top()  << "\n"; // 调试代码 -> 写报告 -> 会议准备tasks.pop(); }std::cout << "剩余任务: " << tasks.size();  // 0return 0;
}

输出结果:
最大堆顶部: 50
最小堆顶部: 10

容器初始化堆顶: 25

任务数量: 3
是否为空: 否

任务处理顺序:
正在处理: 调试代码
正在处理: 写报告
正在处理: 会议准备
剩余任务: 0

  • 使用方法详解
    📦 构造初始化方式
    | 方法 | 示例 | 说明 |
    |------|------|------|
    | 默认构造 | priority_queue<int> maxHeap; | 最大堆(大值优先) |
    | 自定义比较器构造 | priority_queue<int, vector<int>, greater<int>> minHeap; | 最小堆(小值优先) |
    | 容器初始化 | priority_queue<int> q(vec.begin(), vec.end()); | 通过迭代器范围构造 |

⚙️ 元素操作

操作函数特性
添加元素push(val) / emplace(args...)emplace避免拷贝,效率更高
访问顶部top()只读操作,不改变堆结构
移除顶部pop()移除当前最高优先级元素
容量查询size() / empty()常数时间复杂度 O(1)

🔄 高级操作

// 交换两个优先队列 
std::priority_queue<int> pq1, pq2;
pq1.swap(pq2);  // 自定义数据结构排序 
struct Task {int priority;std::string name;bool operator<(const Task& t) const { return priority < t.priority; // 按优先级降序}
};
std::priority_queue<Task> taskQueue;
http://www.xdnf.cn/news/1323937.html

相关文章:

  • 系统架构评估方法全景解析
  • 【Java基础常见辨析】重载与重写,深拷贝与浅拷贝,抽象类与普通类
  • LLM - MCP传输协议解读:从SSE的单向奔赴到Streamable HTTP的双向融合
  • mq存量消息如何处理
  • 【iOS】Block补充
  • RecSys:排序中的融分公式与视频播放建模
  • 数据结构(03)——线性表(顺序存储和链式存储)
  • 从哲学(业务)视角看待数据挖掘:从认知到实践的螺旋上升
  • 常见的光源频闪控制方式
  • CSDN转PDF【无水印且免费!!!】
  • 数字时代著作权侵权:一场资本与法律的博弈
  • Gartner发布2025年AI与网络安全成熟度曲线:用AI增强网络安全计划的27项技术与创新
  • C++ const
  • Swift 实战:判断点集是否关于某条直线对称(LeetCode 356)
  • Effective C++ 条款48:认识模板元编程
  • 【前端面试题】JavaScript 核心知识点解析(第一题到第十三题)
  • 【Python语法基础学习笔记】条件表达式和逻辑表达式
  • 03.文件管理和操作命令
  • 网站服务器使用免费SSL证书安全吗?
  • 免费又强大的 PDF 编辑器 ——PDF XChange Editor
  • MacOS 安全机制与“文件已损坏”排查完整指南
  • 【Tech Arch】Spark为何成为大数据引擎之王
  • 算法题打卡力扣第26. 删除有序数组中的重复项(easy))
  • Linux 中断机制深度分析
  • 【轨物交流】轨物科技与华为鲲鹏生态深度合作 光伏清洁机器人解决方案获技术认证!
  • nuScence数据集
  • 特种行业许可证识别技术:通过图像处理、OCR和结构化提取,实现高效、准确的许可证核验与管理
  • Android Cutout(屏幕挖孔)详解
  • Python day48.
  • 【笔记ing】考试脑科学 脑科学中的高效记忆法