c++中priority_queue怎么用_c++优先队列使用指南【教程】

发布时间 - 2026-01-30 00:00:00    点击率:
priority_queue 默认是最大堆,因第三模板参数默认为 std::less,其调用 a

直接说结论:priority_queue 默认是最大堆,不是最小堆;想用最小堆必须显式指定比较器,否则 top() 返回的是最大值,不是你想要的“优先级最高”的最小耗时/最小距离等。

为什么 priority_queue 默认是最大堆?

因为它的第三个模板参数默认是 std::less,而 std::lessa 为真时返回 true —— 这会让大数“优先级

更高”,所以堆顶始终是最大元素。

常见误用场景:写 Dijkstra 或 BFS 求最短路时,把 pair(距离, 节点)塞进去,结果每次 top() 取出的是距离最大的节点,算法直接跑飞。

  • 要最小堆(小距离优先):用 priority_queue, vector>, greater>>
  • 更稳妥写法(避免依赖 greaterpair 的特化):priority_queue, vector>, greater(C++14 起支持透明比较器)
  • 自定义结构体?必须重载 operator,且注意语义:如果希望 a “优先级高于” b 时先弹出 a,那就要让 a 返回 false(即按“优先级升序”排,但底层仍按 less 解释)—— 更建议直接传 lambda 或 functor

怎么用 lambda 自定义比较器?

priority_queue 的比较器必须满足严格弱序,且不能是普通 lambda(有闭包,无法作为模板参数),但可以用 decltype + auto 配合 vector 构造:

auto cmp = [](const pair& a, const pair& b) {
    return a.first > b.first; // 小 first 先出队 → 最小堆
};
priority_queue, vector>, decltype(cmp)> pq(cmp);

注意:必须把 cmp 实例传给构造函数,否则运行时报错(空比较器未初始化)。

  • lambda 里写 a.first > b.first → 小值优先
  • a.first → 大值优先(等效默认 less
  • 不要试图用 [&] 捕获外部变量,会导致类型不可比较或编译失败

pushtoppop 的性能和线程安全

所有操作平均时间复杂度都是 O(log n),top() 是 O(1);内部用 vector 实现,不支持迭代器遍历,也不能像 set 那样查某元素是否存在。

  • 没有 findcontains 成员函数 —— 想查元素得自己维护一个额外哈希表
  • 不是线程安全的:多线程读写必须加锁,哪怕只读 top()empty() 也要注意竞态(empty() 后可能立刻被 pop)
  • pop() 不返回值,必须先 top()pop(),别指望它像 Python 的 heappop

最容易忽略的一点:修改已入队元素的值不会触发堆调整。比如存了 struct Node { int cost; int id; };,push 后改了某个 Node.cost,堆结构完全不变 —— 此时要么重新 push 新对象,要么换用 std::set


# python  # node  # app  # ai  # c++  # cos  # 为什么  # less  #   # 算法  # 的是  # 大堆  # 自定义  # 都是  # 特化  # 升序  # 也不  # 那就  # 也要  # 可以用 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何连接多个数据库_Laravel多数据库连接配置与切换教程  javascript中的try catch异常捕获机制用法分析  Laravel如何设置定时任务(Cron Job)_Laravel调度器与任务计划配置  如何用PHP工具快速搭建高效网站?  js代码实现下拉菜单【推荐】  在线制作视频的网站有哪些,电脑如何制作视频短片?  如何在阿里云通过域名搭建网站?  Laravel Eloquent关联是什么_Laravel模型一对一与一对多关系精讲  如何构建满足综合性能需求的优质建站方案?  C#如何调用原生C++ COM对象详解  HTML5空格在Angular项目里怎么处理_Angular中空格的渲染问题【详解】  Python3.6正式版新特性预览  原生JS实现图片轮播切换效果  如何用搬瓦工VPS快速搭建个人网站?  Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】  如何在Ubuntu系统下快速搭建WordPress个人网站?  高端建站三要素:定制模板、企业官网与响应式设计优化  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】  如何实现建站之星域名转发设置?  Laravel定时任务怎么设置_Laravel Crontab调度器配置  Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】  开心动漫网站制作软件下载,十分开心动画为何停播?  昵图网官网入口 昵图网素材平台官方入口  Laravel怎么判断请求类型_Laravel Request isMethod用法  b2c电商网站制作流程,b2c水平综合的电商平台?  英语简历制作免费网站推荐,如何将简历翻译成英文?  laravel怎么实现图片的压缩和裁剪_laravel图片压缩与裁剪方法  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  南京网站制作费用,南京远驱官方网站?  油猴 教程,油猴搜脚本为什么会网页无法显示?  PHP怎么接收前端传的文件路径_处理文件路径参数接收方法【汇总】  php json中文编码为null的解决办法  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  如何在新浪SAE免费搭建个人博客?  JavaScript如何实现类型判断_typeof和instanceof有什么区别  Java Adapter 适配器模式(类适配器,对象适配器)优缺点对比  大连网站制作公司哪家好一点,大连买房网站哪个好?  js实现获取鼠标当前的位置  Laravel怎么清理缓存_Laravel optimize clear命令详解  Laravel如何创建自定义Facades?(详细步骤)  Edge浏览器如何截图和滚动截图_微软Edge网页捕获功能使用教程【技巧】  使用Dockerfile构建java web环境  Laravel怎么实现模型属性的自动加密  Laravel如何记录自定义日志?(Log频道配置)  Laravel如何配置和使用缓存?(Redis代码示例)  香港服务器网站卡顿?如何解决网络延迟与负载问题?  ,在苏州找工作,上哪个网站比较好?