当前位置: 首页 > 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.lryc.cn/news/624577.html

相关文章:

  • 贪心算法(Greedy Algorithm)详解
  • 【C语言】gets和getchar的区别
  • 深度优先遍历dfs(模板)
  • 具身智能2硬件架构(人形机器人)摘自Openloong社区
  • 数据结构:查找表
  • 宏观认识 Unitree LiDAR L1 及其在自动驾驶中的应用
  • 【opencv-Python学习日记(7):图像平滑处理】
  • 阿里云odps和dataworks的区别
  • Poisson分布:稀有事件建模的理论基石与演进
  • 前端纯JS实现手绘地图 地图导引
  • YAML 语法结构速查表(完整版)
  • 【tips】unsafe-eval线上页面突然空白
  • Lucene 8.5.0 的 `.pos` 文件**逻辑结构**
  • 永磁同步电机控制算法--转速环电流环超螺旋滑模控制器STASMC
  • 大数据毕业设计选题推荐:基于Hadoop+Spark的城镇居民食品消费分析系统源码
  • 【项目】分布式Json-RPC框架 - 项目介绍与前置知识准备
  • 将 iPhone 联系人转移到 Infinix 的完整指南
  • Zephyr下ESP32S3开发环境搭建(Linux篇)
  • 【Python语法基础学习笔记】常量变量运算符函数
  • 分布式系统的“不可能三角”:CAP定理深度解析
  • flask——4:请求与响应
  • 敏感数据加密平台设计实战:如何为你的系统打造安全“保险柜”
  • 实战演练:通过API获取商品详情并展示
  • pytest的前置与后置
  • 【笔记ing】考试脑科学 脑科学中的高效记忆法
  • c++26新功能—可观测检查点
  • 晨控CK-GW08S与欧姆龙PLC配置Ethernet/IP通讯连接手册
  • PHP现代化全栈开发:微前端架构与模块化实践
  • 深入解析RabbitMQ与AMQP-CPP:从原理到实战应用
  • Elasticsearch全文检索中文分词:IK分词器详解与Docker环境集成