C++ 怎么实现堆排序 C++ make_heap与sort_heap使用【STL】
发布时间 - 2026-01-29 00:00:00 点击率:次make_heap仅构建堆结构而不排序,需配合sort_heap才能完成排序;它时间复杂度O(n),但要求输入为随机访问迭代器,且必须与sort_heap使用相同比较函数。
make_heap 为什么不能直接当排序用
make_heap 只把容器转成最大堆(或最小堆),不保证元素有序。它只调整结构满足堆性质:每个节点值 ≥(或 ≤)其子节点,但根最大、叶子最小,并不等于“从大到小排列”。常见误用是调完 make_heap 就以为排好了,结果一打印发现顺序乱的。
典型场景:你有一段 vector,执行 make_heap(v.begin(), v.end()); 后,v 可能变成 {5,3,4,1,1} —— 满足堆序,但不是升序/降序。
- 默认构造最大堆(
less),想最小堆得显式传greater() - 时间复杂度 O(n),但只是建堆,不是排序
- 底层依赖随机访问迭代器,
list不能用
sort_heap 必须在 make_heap 之后调用
sort_heap 的前提条件很硬:它要求输入区间**已经是合法堆**。如果直接对普通数组调 sort_heap,行为未定义,大概率崩溃或输出垃圾数据。错误现象包括:程序闪退、部分元素重复、最后几个数完全错位。
正确链条只有这一种:make_heap → (可选 push_heap/pop_heap)→ sort_heap。其中 sort_heap 是个“一次性操作”:它把堆逐个弹出最大元放到末尾,最终得到升序序列(对最大堆而言)。
- 对最大堆调
sort_heap得升序;若要降序,先用greater建最小堆,再调() sort_heap - 调用后原堆结构被破坏,不能再当堆用
- 必须和
make_heap用同一比较函数,否则结果不可预测
完整堆排序三步写法(含自定义比较)
标准堆排序流程就是三行 STL 调用,但每行参数必须对齐。例如按绝对值升序排:
vectorv = {-3, 2, -1, 4}; auto abs_less = [](int a, int b) { return abs(a) < abs(b); }; make_heap(v.begin(), v.end(), abs_less); sort_heap(v.begin(), v.end(), abs_less); // v 现在是 {-1, 2, -3, 4}(abs: 1,2,3,4)
注意点:
- lambda 捕获为空时才能作为模板参数,所以不能带
[&]或[=] - 如果用函数对象(如
struct AbsLess { bool operator()(...) {...} };),要确保operator()是 const -
sort_heap不接受std::execution::par等策略,纯串行
性能与边界提醒:别在 vector 外反复调 heap 函数
STL 堆函数都假设容器内存连续且迭代器有效。vector 中间 erase 或 insert 后,原有堆结构全失效,必须重调 make_heap,不能靠 push_heap 补救——因为 push_heap 只处理“最后一个元素插入后”的情况,前提是前面仍是堆。
另一个易忽略点:make_heap 和 sort_heap 对空区间或单元素区间安全,但传入 v.end() 和 v.end() 这种无效范围会 UB。调试时建议加 assert:
assert(first != last && "heap op on empty range");
实际项目里,如果排序是唯一目标,直接用 std::sort 更快更稳;STL 堆函数真正价值在于需要动态维护堆结构的场景,比如优先队列底层、Top-K 流式计算——这时候才轮到 push_heap/pop_heap 上场。
# c++
# 排列
# 为什么
# less
# sort
# const
# bool
# Lambda
# 堆
# Struct
# operator
# 对象
# 升序
# 大堆
# 迭代
# 这一
# 是个
# 好了
# 降序
# 你有
# 而不
# 仍是
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何在Windows服务器上快速搭建网站?
Laravel Blade模板引擎语法_Laravel Blade布局继承用法
php中::能调用final静态方法吗_final修饰静态方法调用规则【解答】
JavaScript Ajax实现异步通信
如何在建站宝盒中设置产品搜索功能?
免费网站制作appp,免费制作app哪个平台好?
jquery插件bootstrapValidator表单验证详解
EditPlus中的正则表达式实战(5)
javascript如何操作浏览器历史记录_怎样实现无刷新导航
Laravel如何实现用户注册和登录?(Auth脚手架指南)
node.js报错:Cannot find module 'ejs'的解决办法
Android GridView 滑动条设置一直显示状态(推荐)
Laravel如何使用缓存系统提升性能_Laravel缓存驱动和应用优化方案
Laravel Admin后台管理框架推荐_Laravel快速开发后台工具
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
如何基于PHP生成高效IDC网络公司建站源码?
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
如何用西部建站助手快速创建专业网站?
php json中文编码为null的解决办法
企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?
如何快速搭建高效WAP手机网站?
Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】
JS中对数组元素进行增删改移的方法总结
浅谈redis在项目中的应用
如何在 Pandas 中基于一列条件计算另一列的分组均值
javascript基本数据类型及类型检测常用方法小结
东莞专业网站制作公司有哪些,东莞招聘网站哪个好?
Claude怎样写约束型提示词_Claude约束提示词写法【教程】
实例解析Array和String方法
Python自动化办公教程_ExcelWordPDF批量处理案例
Laravel观察者模式如何使用_Laravel Model Observer配置
如何批量查询域名的建站时间记录?
如何在景安服务器上快速搭建个人网站?
EditPlus中的正则表达式实战(6)
如何快速查询域名建站关键信息?
如何快速登录WAP自助建站平台?
大同网页,大同瑞慈医院官网?
Laravel怎么实现观察者模式Observer_Laravel模型事件监听与解耦开发【指南】
青岛网站建设如何选择本地服务器?
Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制
如何快速搭建FTP站点实现文件共享?
Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】
Laravel如何发送系统通知?(Notification渠道示例)
Laravel如何使用Blade组件和插槽?(Component代码示例)
Laravel如何实现本地化和多语言支持?(i18n教程)
Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解
Edge浏览器提示“由你的组织管理”怎么解决_去除浏览器托管提示【修复】
javascript事件捕获机制【深入分析IE和DOM中的事件模型】
Laravel如何与Pusher实现实时通信?(WebSocket示例)
极客网站有哪些,DoNews、36氪、爱范儿、虎嗅、雷锋网、极客公园这些互联网媒体网站有什么差异?


