0

0

c++中priority_queue怎么自定义排序_c++优先队列【教程】

尼克

尼克

发布时间:2026-02-08 14:51:09

|

340人浏览过

|

来源于php中文网

原创

priority_queue 默认是大根堆,top() 返回最大元素;底层使用 std::less,即 a b.x。

c++中priority_queue怎么自定义排序_c++优先队列【教程】

priority_queue 默认是大根堆还是小根堆?

默认是大根堆,也就是 top() 返回最大元素。底层用 std::less 作为比较器,等价于 a —— 注意:这个“小于”决定的是「谁该被优先弹出」的逻辑反向:当 comp(a, b) 为 true,表示 a 应该排在 b **之前**(即更“优先”),但 priority_queue 的堆结构实际按「父节点比子节点大」组织,所以 less 导致最大值在顶。

常见误解:以为 less 就是“小的优先”,其实它控制的是堆的排序谓词,不是直观的“升序/降序”。

  • 要小根堆(最小值在 top()):传 std::greater
  • 自定义类型必须提供可调用的比较对象,不能只重载 operator 就完事(除非你用默认模板参数)
  • 注意第三个模板参数是类型,不是实例:priority_queue, greater>,不是 greater()

怎么给 struct 自定义 priority_queue 比较规则?

最稳妥的方式是单独写一个仿函数(functor)或用 lambda(C++20 起支持,但需配合 decltype 且不能直接用于模板参数)。推荐 functor:

struct Node {
    int x, y;
    Node(int x, int y) : x(x), y(y) {}
};

struct Compare {
    bool operator()(const Node& a, const Node& b) {
        return a.x > b.x; // 小根堆按 x 排;注意:这里写 > 表示“a 优先级低于 b”时返回 true,即 a 应该沉下去
    }
};

priority_queue, Compare> pq;
  • 函数体里写 a.x > b.x 才能得到「x 小的在 top」—— 因为 priority_queue 把返回 true 的 pair 当作「a 不如 b 优先」来调整堆
  • 如果用 auto cmp = [](const Node& a, const Node& b) { return a.x > b.x; };,不能直接塞进模板参数,得用 priority_queue, decltype(cmp)> pq(cmp);(C++11 起支持带状态的比较器)
  • 别在 operator 里改逻辑来凑合:容易和 set/map 行为冲突,语义混乱

为什么用了 greater 还报错 “no match for operator

典型错误场景:对自定义类型写 priority_queue, greater>,编译失败提示找不到 operator。

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

原因:std::greater 内部仍会调用 operator(它等价于 return b ),所以最终还是依赖 T 支持 。它不是“绕过比较”,而是“换一种方式调用”。

  • 正确解法:要么实现 bool operator,要么不使用 greater,改用显式 functor 或 lambda
  • 如果类有多个字段想复合排序(比如先按 cost 升序,再按 id 降序),greater 完全无能为力,必须手写比较逻辑
  • 注意:即使你只用 priority_queue,也建议把 operator 定义成符合直觉的“严格弱序”(如升序),避免其他容器误用时行为不一致

用 vector 初始化 priority_queue 时排序规则生效吗?

生效,但仅限于构造时一次性建堆。例如:

vector v = {3, 1, 4};
priority_queue, greater> pq(v.begin(), v.end());
// pq.top() == 1 ✅
  • 底层调用的是 make_heap,时间复杂度 O(n),不是逐个 push 的 O(n log n)
  • 但 vector 必须是可随机访问的容器;如果是 list 或其他,无法直接初始化
  • 初始化后所有后续操作(push/pop)都继续遵守该比较规则,不会回退到默认
  • 如果 vector 本身已按某种顺序排好,别指望它“保持原序”——堆结构必然重排
真正容易被忽略的是比较器的语义方向:写 a 还是 a > b,不取决于你想“升序”还是“降序”,而取决于你希望「谁留在 top」。多调试一次 top() 输出,比查三遍文档更快。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

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

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

208

2023.10.12

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

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

540

2023.09.20

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

404

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

584

2023.08.10

Golang处理数据库错误教程合集
Golang处理数据库错误教程合集

本专题整合了Golang数据库错误处理方法、技巧、管理策略相关内容,阅读专题下面的文章了解更多详细内容。

65

2026.02.06

java多线程方法汇总
java多线程方法汇总

本专题整合了java多线程面试题、实现函数、执行并发相关内容,阅读专题下面的文章了解更多详细内容。

32

2026.02.06

1688阿里巴巴货源平台入口与批发采购指南
1688阿里巴巴货源平台入口与批发采购指南

本专题整理了1688阿里巴巴批发进货平台的最新入口地址与在线采购指南,帮助用户快速找到官方网站入口,了解如何进行批发采购、货源选择以及厂家直销等功能,提升采购效率与平台使用体验。

488

2026.02.06

快手网页版入口与电脑端使用指南 快手官方短视频观看入口
快手网页版入口与电脑端使用指南 快手官方短视频观看入口

本专题汇总了快手网页版的最新入口地址和电脑版使用方法,详细提供快手官网直接访问链接、网页端操作教程,以及如何无需下载安装直接观看短视频的方式,帮助用户轻松浏览和观看快手短视频内容。

265

2026.02.06

C# 多线程与异步编程
C# 多线程与异步编程

本专题深入讲解 C# 中多线程与异步编程的核心概念与实战技巧,包括线程池管理、Task 类的使用、async/await 异步编程模式、并发控制与线程同步、死锁与竞态条件的解决方案。通过实际项目,帮助开发者掌握 如何在 C# 中构建高并发、低延迟的异步系统,提升应用性能和响应速度。

18

2026.02.06

热门下载

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

精品课程

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

共102课时 | 6.9万人学习

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

共162课时 | 19.5万人学习

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

共119课时 | 12.7万人学习

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

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