当前位置: 首页 > 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.dtcms.com/a/337343.html

相关文章:

  • 力扣(LeetCode) ——100. 相同的树(C语言)
  • 算法-每日一题(DAY13)两数之和
  • 排序(Java实现)
  • Dijkstra和多层图 0
  • 蓝桥杯算法之搜索章 - 7
  • LeetCode 45.跳跃游戏II:贪心策略下的最少跳跃次数求解
  • 华为云服务器从注册到部署全流程指南
  • Pomian语言处理器 研发笔记(一):使用C++的正则表达式构建词法分析器
  • 零基础数据结构与算法——第七章:算法实践与工程应用-图像处理
  • LLM - MCP传输协议解读:从SSE的单向奔赴到Streamable HTTP的双向融合
  • JavaScript 原型继承与属性访问规则详解
  • ES入门教程
  • CSDN转PDF【无水印且免费!!!】
  • linux 内核 - 进程地址空间的数据结构
  • 【STM32】STM32H750 CubeMX 配置 USB CDC 虚拟串口笔记
  • 保姆级教学:使用 Jenkins 部署前端项目(2025 年最新版)
  • 基于JS实现的中国象棋AI系统:多模块协同决策与分析
  • ffmpeg编译
  • 音视频面试题集锦第 26 期
  • 计算机网络-IPv6
  • 679. 24 点游戏
  • Android Cutout(屏幕挖孔)详解
  • ubuntu 编译ffmpeg6.1 增加drawtext,libx264,libx265等
  • Leetcode 3648. Minimum Sensors to Cover Grid
  • OCR库pytesseract安装保姆级教程
  • LeetCode:无重复字符的最长子串
  • SQLite 加密与不加密性能对比与优化实践
  • Opsqueue:为重负载而生的轻量级批处理队列,已开源!
  • 视频因为264问题无法网页播放,解决方案之一:转化视频
  • 智创飞跃|2025 Google 开发者大会伴你成长精进