首页 > 后端开发 > C++ > 正文

如何使用C++的priority_queue 最大堆最小堆实现原理

P粉602998670
发布: 2025-07-14 08:02:02
原创
884人浏览过

如何在 c++++ 中使用 priority_queue 实现最大堆和最小堆?1. 默认情况下,priority_queue 是最大堆,如 std::priority_queue<int> max_heap; 可实现每次获取最大值;2. 要实现最小堆,需指定第三个模板参数为 std::greater<int>,如 std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap; 以构建最小堆;3. 自定义类型时,应提供比较函数对象,如定义 comparetask 结构体重载 operator() 按 priority 构建最小堆;4. 底层原理基于数组实现的完全二叉树结构,push 和 pop 操作分别触发向上和向下调整;5. 注意 priority_queue 不支持遍历和动态修改元素,适合固定优先级场景。

如何使用C++的priority_queue 最大堆最小堆实现原理

在 C++ 中,priority_queue 是一个常用的容器适配器,用来实现堆结构。默认情况下,它是一个最大堆(也就是每次取的是当前堆中最大的元素),但通过传入不同的比较函数,也可以轻松实现最小堆

如何使用C++的priority_queue 最大堆最小堆实现原理

最大堆的使用方法

默认情况下,priority_queue 就是最大堆。比如:

#include <queue>
std::priority_queue<int> max_heap;
登录后复制

这样声明之后,max_heap.top() 返回的就是当前堆中的最大值。

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

如何使用C++的priority_queue 最大堆最小堆实现原理

添加元素用 push(),删除顶部元素用 pop(),判断是否为空用 empty(),这些和其它 STL 容器类似。

举个简单的例子:

如何使用C++的priority_queue 最大堆最小堆实现原理
max_heap.push(3);
max_heap.push(1);
max_heap.push(5);

cout << max_heap.top();  // 输出 5
登录后复制

虽然你插入顺序是 3、1、5,但堆内部自动调整结构,保证最大值始终在顶部。


最小堆怎么实现?

C++ 的 priority_queue 默认不支持最小堆,需要我们手动指定比较函数。通常使用 greater<int> 这个内置的比较器来实现:

#include <queue>
#include <functional>

std::priority_queue<int, std::vector<int>, std::greater<int>> min_heap;
登录后复制

注意模板参数有三个:

堆友
堆友

Alibaba Design打造的设计师全成长周期服务平台,旨在成为设计师的好朋友

堆友 306
查看详情 堆友
  • 第一个是数据类型 int
  • 第二个是底层容器,默认是 vector<int>
  • 第三个是比较方式,这里用了 greater,也就是“大于”关系,从而构建最小堆

使用起来也是一样:

min_heap.push(4);
min_heap.push(2);
min_heap.push(6);

cout << min_heap.top();  // 输出 2
登录后复制

堆的实现原理简要说明

堆本质上是一种完全二叉树结构,通常用数组实现。最大堆和最小堆的区别在于节点之间的大小关系:

  • 最大堆:父节点的值总是大于等于子节点。
  • 最小堆:父节点的值总是小于等于子节点。

当调用 push() 时,新元素被放到数组末尾,然后向上调整(heapify up)以保持堆的性质; 当调用 pop() 时,根节点被移除,最后一个元素移到根位置,然后向下调整(heapify down)。

STL 中的 priority_queue 底层就是基于这样的逻辑实现的,只是把比较方式封装成了模板参数。


自定义类型的堆怎么写?

如果你要用自定义类型(比如结构体或类),就需要自己写比较函数或者重载操作符。

比如有一个表示任务优先级的结构体:

struct Task {
    int priority;
    string name;
};
登录后复制

你想按 priority 构建最小堆,可以这样做:

struct CompareTask {
    bool operator()(const Task& a, const Task& b) {
        return a.priority > b.priority;  // 最小堆
    }
};

std::priority_queue<Task, std::vector<Task>, CompareTask> task_queue;
登录后复制

这样就能根据 priority 来排序了。这个技巧在算法题或调度系统中非常实用。


使用注意事项

  • priority_queue 不支持直接遍历,只能通过 top()pop() 一个个访问。
  • 插入和弹出的时间复杂度都是 O(log n),效率还不错。
  • 如果你需要动态修改堆中的某个元素并重新调整堆,那就不适合用 priority_queue,建议换用 set 或者手写堆结构。

基本上就这些。理解最大堆和最小堆的实现差异,以及如何用模板参数控制比较方式,就可以灵活应对各种场景了。

以上就是如何使用C++的priority_queue 最大堆最小堆实现原理的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

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