0

0

C++优先队列怎么用 C++ priority_queue大顶堆小顶堆用法【高阶】

冰火之心

冰火之心

发布时间:2026-01-28 12:26:02

|

521人浏览过

|

来源于php中文网

原创

priority_queue默认是大顶堆,top()返回最大元素;其第三个模板参数默认为std::less,基于operator

c++优先队列怎么用 c++ priority_queue大顶堆小顶堆用法【高阶】

priority_queue 默认是大顶堆还是小顶堆

默认是大顶堆——也就是 top() 返回最大元素。这是因为它的第三个模板参数默认是 std::less,而 std::less 在底层调用 operator,导致堆按“父节点 > 子节点”维护,即最大堆。

容易踩的坑:误以为“优先级高就排前面”等于“数值小优先”,结果发现 priority_queue 弹出的是最大值,和预期相反。

  • 要小顶堆,必须显式传入 std::greater(需 #include
  • std::greater 要求 T 支持 operator>;自定义类型需重载该运算符,或提供仿函数
  • 别写成 priority_queue, greater(C++20 之前不支持类模板参数推导,必须写 greater

自定义比较器实现小顶堆(含结构体)

对结构体或复杂类型,不能只靠 greater,得自己写比较逻辑。关键是:priority_queue 的比较器定义的是“是否应该排在后面”,即 comp(a, b) == true 表示 a 应该比 b 更“靠后”(即 b 优先级更高)。

所以小顶堆的比较器实际是“a > b”,不是“a

立即学习C++免费学习笔记(深入)”;

struct Node {
    int val;
    int id;
};
// 小顶堆:按 val 升序;val 相同时按 id 升序
auto cmp = [](const Node& a, const Node& b) { 
    return a.val > b.val || (a.val == b.val && a.id > b.id); 
};
priority_queue, decltype(cmp)> pq(cmp);
  • lambda 必须捕获为空(否则不能作为模板参数),所以用 decltype(cmp) + 构造函数传入实例
  • 如果用 functor 类,需确保 operator() 是 const 且 noexcept(尤其在性能敏感场景)
  • 别在比较器里做耗时操作(如字符串比较、IO),它会在每次 push/pop 时频繁调用

priority_queue 没有迭代器,怎么调试或遍历

它不提供迭代器接口,也不能直接访问内部容器。强行遍历时,唯一安全的方式是「拷贝后逐个弹出」,但会清空原队列。

奇布塔
奇布塔

基于AI生成技术的一站式有声绘本创作平台

下载

调试建议:

  • 临时改用 vector + make_heap/push_heap/pop_heap,它们允许直接访问底层 vector
  • 用 IDE 的内存视图看其内部 c 成员(比如在 GDB 中 p pq.c),但这依赖实现,不跨平台
  • 封装一层带日志的 wrapper:每次 push 记录,top 前断点,避免依赖遍历

注意:priority_queue 的底层容器默认是 vector,但你不能假设 pq.size()vector 下标一一对应——因为堆结构是完全二叉树映射,顺序不是插入顺序。

性能与替代方案:什么时候不该用 priority_queue

单次 push/pop 是 O(log n),看着不错,但常被忽略的是:它不支持修改已有元素优先级(decrease-key),也不支持按值删除。

  • 需要动态调整优先级?考虑 std::set 或手写配对堆 / 斐波那契堆(后者 STL 没提供)
  • 需要删除任意元素?用 set + 自定义比较,或标记删除 + 惰性清理(while (!pq.empty() && deleted[pq.top()]) pq.pop();
  • 元素极少(n )?直接用 vector + min_element 可能更快,避免堆维护开销

真正关键的不是“会不会用”,而是清楚它只适合“只增删顶、不改中”的场景——一旦需求越界,硬套只会让代码越来越难维护。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Sass和less的区别
Sass和less的区别

Sass和less的区别有语法差异、变量和混合器的定义方式、导入方式、运算符的支持、扩展性等。本专题为大家提供Sass和less相关的文章、下载、课程内容,供大家免费下载体验。

203

2023.10.12

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1500

2023.10.24

Go语言中的运算符有哪些
Go语言中的运算符有哪些

Go语言中的运算符有:1、加法运算符;2、减法运算符;3、乘法运算符;4、除法运算符;5、取余运算符;6、比较运算符;7、位运算符;8、按位与运算符;9、按位或运算符;10、按位异或运算符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

231

2024.02.23

php三元运算符用法
php三元运算符用法

本专题整合了php三元运算符相关教程,阅读专题下面的文章了解更多详细内容。

87

2025.10.17

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

94

2023.09.25

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

530

2023.09.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

298

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

俄罗斯Yandex引擎入口
俄罗斯Yandex引擎入口

2026年俄罗斯Yandex搜索引擎最新入口汇总,涵盖免登录、多语言支持、无广告视频播放及本地化服务等核心功能。阅读专题下面的文章了解更多详细内容。

69

2026.01.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
HTML5/CSS3/JavaScript/ES6入门课程
HTML5/CSS3/JavaScript/ES6入门课程

共102课时 | 6.8万人学习

前端基础到实战(HTML5+CSS3+ES6+NPM)
前端基础到实战(HTML5+CSS3+ES6+NPM)

共162课时 | 19.1万人学习

第二十二期_前端开发
第二十二期_前端开发

共119课时 | 12.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号