0

0

C++中的std::priority_queue如何实现小顶堆?(修改模板参数中的比较器)

冰火之心

冰火之心

发布时间:2026-01-18 16:39:55

|

652人浏览过

|

来源于php中文网

原创

std::priority_queue默认是大顶堆,因其第三个模板参数Compare默认为std::less,它使较小元素优先级更高;改为小顶堆需显式传入std::greater或自定义仿函数,且要求类型支持operator>或在仿函数中正确实现a>b表示a优先级更低。

c++中的std::priority_queue如何实现小顶堆?(修改模板参数中的比较器)

默认情况下 std::priority_queue 是大顶堆,要变成小顶堆,必须显式替换比较器模板参数,不能只靠 std::greater 就完事——它只是其中一种可行方式,且有前提条件。

为什么默认不是小顶堆?

std::priority_queue 的第三个模板参数是 Compare,类型为 bool( const T&, const T& ) 的可调用对象,默认是 std::less。而 std::less 返回 a ,导致“更大的元素优先出队”,即大顶堆。

小顶堆要求“更小的元素优先出队”,所以比较器逻辑应让 a > b 时返回 true(即:当 a 应该排在 b 后面时,认为 a “优先级更低”)。

正确写法:用 std::greater 或自定义仿函数

最常用且安全的方式是传入 std::greater,但它要求 T 支持 operator>;若自定义类型未重载 >,则编译失败。

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

Sitekick
Sitekick

一个AI登陆页面自动构建器

下载
  • 对内置类型(如 int, double)直接可用:
    std::priority_queue, std::greater> min_heap;
  • 对自定义结构体,需提供 operator> 或用 lambda(C++20 起支持,但需配合 std::priority_queue 的容器适配限制);更稳妥的是写仿函数:
    struct Compare {
        bool operator()(const MyStruct& a, const MyStruct& b) {
            return a.value > b.value; // 注意:这里 a > b 表示 a 优先级更低
        }
    };
    std::priority_queue, Compare> min_heap;

常见错误:误用 std::less 或反向写比较逻辑

以下写法都是错的:

  • 写成 std::less:仍是大顶堆
  • 写成 std::greater 但忘了指定容器类型(第二个模板参数):默认是 std::vector,但若手动写了其他容器(如 std::deque),必须显式写出全部三个参数
  • 自定义比较器里写 return a.value :这反而实现的是大顶堆逻辑
  • 以为用 std::priority_queuetop() 取最小值就等于小顶堆——其实只是碰巧当前 top 是最小,内部结构仍是大顶堆,pop 后行为不可预期

性能与底层容器的影响

std::priority_queue 是适配器,底层默认用 std::vector,所有操作时间复杂度不变(push/pop 是 O(log n))。但若换成 std::deque,虽合法,却可能因缓存不友好略微变慢;std::list 则完全不可用——它不支持随机访问,无法建堆。

真正容易被忽略的是:比较器类型必须满足严格弱序(strict weak ordering),否则行为未定义。比如用 != 实现比较器,会导致 push 崩溃或死循环。

相关专题

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

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

200

2023.10.12

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

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

524

2023.09.20

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

196

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

189

2025.07.04

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

196

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

189

2025.07.04

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

318

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

538

2024.08.29

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

65

2026.01.16

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 6.9万人学习

C 教程
C 教程

共75课时 | 4.1万人学习

C++教程
C++教程

共115课时 | 12.6万人学习

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

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