0

0

c++如何实现堆排序_c++ heap算法应用详解【进阶】

裘德小鎮的故事

裘德小鎮的故事

发布时间:2026-02-09 01:31:07

|

954人浏览过

|

来源于php中文网

原创

std::make_heap只构建堆结构而非全序排列,因堆仅保证父节点不小于子节点且满足完全二叉树性质,故容器仍显“乱序”;需配合std::pop_heap循环将堆顶移至末尾并调整剩余部分才能完成升序排序。

c++如何实现堆排序_c++ heap算法应用详解【进阶】

为什么 std::make_heap 不能直接排序?

很多人调用 std::make_heap 后发现容器没按升序排列,就以为“堆排序失败”——其实这是对堆结构的误解。堆(默认大根堆)只保证 *(begin) ≥ *(begin+1) 且满足完全二叉树父子关系,**不保证整体有序**。真正排序必须配合 std::pop_heap 循环弹出最大值到末尾。

  • std::make_heap 只建堆,时间复杂度 O(n),但数组仍是“堆序”,不是“全序”
  • 要得到升序结果,需重复执行:std::pop_heap(把堆顶换到末尾 + 重排剩余部分),再收缩范围
  • 错误写法:std::make_heap(v.begin(), v.end()); → 此时 v 仍是乱序的(只是满足堆性质)

手写堆排序 vs std::sort_heap:什么时候该自己实现?

std::sort_heap标准库提供的“堆排序收尾操作”,但它**要求输入已是有效堆**。如果你已经用 std::make_heap 建好堆,直接跟 std::sort_heap 就能完成升序排序;但如果需要降序、自定义比较或中间插入/删除,就得手动控制过程。

  • 升序排序(推荐):std::make_heap(v.begin(), v.end()); std::sort_heap(v.begin(), v.end());
  • 降序排序:必须用小根堆,传 std::greater()std::make_heap(v.begin(), v.end(), std::greater());
  • 中途插入元素:用 std::push_heap(先 push_back,再 push_heap
  • 性能注意:std::sort_heap 是 O(n log n),但常数略高于 std::sort;除非明确需要堆的动态特性,否则普通排序优先用 std::sort

std::push_heapstd::pop_heap 的边界陷阱

这两个函数不改变容器大小,只调整逻辑堆范围。最容易出错的是迭代器范围传错,或忘记同步修改容器 size(比如 pop_back)。

  • std::push_heap(v.begin(), v.end()) 要求:最后一个元素是新插入项,且 v.size() > 0
  • std::pop_heap(v.begin(), v.end()) 执行后:最大值被移到 *(v.end()-1),但仍在容器内;必须手动 v.pop_back() 才算真正删除
  • 常见崩溃:std::pop_heap(v.begin(), v.end()); v.pop_back(); 缺一不可,漏掉 pop_back 会导致下次 pop_heap 作用于已无效位置
  • 自定义比较器必须全程一致:建堆、push、pop 都得传同一个 Comp,否则行为未定义

原地堆排序的完整可运行片段(含注释)

#include 
#include 
#include 

int main() {
    std::vector v = {3, 1, 4, 1, 5, 9, 2, 6};

    // 1. 建大根堆(升序准备)
    std::make_heap(v.begin(), v.end());

    // 2. 逐个弹出最大值到末尾
    for (auto it = v.end(); it != v.begin(); --it) {
        std::pop_heap(v.begin(), it); // 把当前堆顶移到 [it-1]
    }

    // 此时 v 已升序 —— 注意:pop_heap 循环本身完成了排序
    for (int x : v) std::cout << x << " "; // 输出:1 1 2 3 4 5 6 9
}

这段代码没调用 std::sort_heap,而是用裸 pop_heap 手动控制每一步。关键点在于循环中 it 是递减的“堆右界”,每次缩小堆范围,最终让所有元素按升序沉淀到前端。这种写法更暴露堆排序本质,也方便在循环中加监控或中断逻辑。

Smodin AI Content Detector
Smodin AI Content Detector

多语种AI内容检测工具

下载

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

真正容易被忽略的,是堆算法对“范围”的严格依赖——所有 xxx_heap 函数都只认你传的迭代器区间,不会检查容器实际 size 或数据一致性。传错一个 end(),结果就不可预测。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

399

2023.09.04

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

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

409

2023.07.18

堆和栈区别
堆和栈区别

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

586

2023.08.10

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

437

2023.08.14

包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法
包子漫画网页版入口与全集阅读指南_正版免费漫画快速访问方法

本专题汇总了包子漫画官网和网页版入口,提供最新章节抢先看方法、正版免费阅读指南,以及稳定访问方式,帮助用户快速直达包子漫画页面,无广告畅享全集漫画内容。

44

2026.02.10

MC.JS网页版快速畅玩指南_MC.JS官网在线入口及免安装体验方法
MC.JS网页版快速畅玩指南_MC.JS官网在线入口及免安装体验方法

本专题汇总了MC.JS官网入口和网页版快速畅玩方法,提供免安装访问、不同版本(1.8.8、1.12.8)在线体验指南,以及正版网页端操作说明,帮助玩家轻松进入MC.JS世界,实现即时畅玩与高效体验。

29

2026.02.10

谷歌邮箱网页版登录与注册全指南_Gmail账号快速访问与安全操作教程
谷歌邮箱网页版登录与注册全指南_Gmail账号快速访问与安全操作教程

本专题汇总了谷歌邮箱网页版的最新登录入口和注册方法,详细提供官方账号快速访问方式、网页版操作教程及安全登录技巧,帮助用户轻松管理Gmail邮箱账户,实现高效、安全的邮箱使用体验。

25

2026.02.10

铁路12306订票与退改全攻略_高效购票与座位选取技巧
铁路12306订票与退改全攻略_高效购票与座位选取技巧

本专题全面汇总铁路12306订票、退票、改签及候补订单操作技巧,提供车厢座位分布参考、抢票攻略和高铁安检注意事项,帮助新手用户快速掌握高效购票与退改流程,提高出行效率和体验。

22

2026.02.10

TensorFlow2深度学习模型实战与优化
TensorFlow2深度学习模型实战与优化

本专题面向 AI 与数据科学开发者,系统讲解 TensorFlow 2 框架下深度学习模型的构建、训练、调优与部署。内容包括神经网络基础、卷积神经网络、循环神经网络、优化算法及模型性能提升技巧。通过实战项目演示,帮助开发者掌握从模型设计到上线的完整流程。

0

2026.02.10

热门下载

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

精品课程

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

共32课时 | 4.9万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

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

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