c++中堆排序算法如何实现_c++ heap sort代码【源码】
发布时间 - 2026-01-28 00:00:00 点击率:次堆排序核心是heapify而非完整堆类实现,应优先使用std::make_heap和std::pop_heap原地排序,建堆O(n),需从下标(n/2)-1开始sift_down,且不稳定、缓存不友好。
堆排序的核心是 heapify 而不是手写完整二叉堆类
多数人误以为堆排序必须先实现一个完整的 Heap 类(带 insert、extract_max 等),其实 C++ 标准库已提供底层支持,且原地排序只需关注 heapify 过程。关键在于:堆排序本质是「建堆 + 反复弹出最大值」,而建堆可以自底向上用 std::make_heap,或手动实现 sift_down 逻辑。
常见错误现象:std::make_heap 后直接遍历数组,发现顺序不对——因为它是最大堆,顶部是最大值,但整个数组不有序;必须配合 std::pop_heap 把最大值逐步移到末尾。
-
std::make_heap时间复杂度 O(n),不是 O(n log n);这是很多人忽略的优化点 - 若用
std::priority_queue实现,会额外分配内存,失去「原地」优势 - 手动实现
heapify时,最后一个非叶子节点下标是(n / 2) - 1,不是n / 2
用 std::make_heap 和 std::pop_heap 组合实现最简版本
这是最贴近算法导论描述、又避免重复造轮子的做法。它不引入额外容器,只操作原始数组,且可复用标准库的健壮性。
void heap_sort(std::vector& arr) { std::make_heap(arr.begin(), arr.end()); // 建最大堆 for (auto it = arr.end(); it != arr.begin(); --it) { std::pop_heap(arr.begin(), it); // 把堆顶移到 [it-1] } }
注意:std::pop_heap 不删除元素,只是把最大值换到当前范围末尾,然后调整剩余部分为堆。所以循环中 it 从 end() 开始递减,每次缩小堆的范围。
- 如果传入
std::vector,需确保有随机访问迭代器(满足) - 排序后是升序;若要降序,改用
std::less作为第三个参数(默认是std::less,即最大堆 → 升序) - 对
int*数组也适用:std::make_heap(ptr, ptr + n)
手动实现 sift_down 时索引边界容易错
当不用标准库、必须手写时,核心是 sift_down 函数:从某节点出发,将其下沉到合适位置。最容易出错的是左右孩子索引计算和越界判断。
假设当前节点下标为 i,则:
- 左孩子:
2 * i + 1(不是2 * i,因数组从 0 开始) - 右孩子:
2 * i + 2 - 检查是否越界:必须同时满足
left 和right ,不能只比arr.size() - 下沉前要先比较左右孩子,选较大者再与父节点交换;否则可能破坏堆性质
建堆阶段必须从最后一个非叶子节点开始倒序调用 sift_down,否则无法保证整体堆结构。这个节点是 (arr.size() / 2) - 1,不是 arr.size() / 2

arr.size() - 1。
性能与稳定性:堆排序不适合小数组,也不稳定
堆排序时间复杂度稳定在 O(n log n),但常数因子比快排大;实际中,STL 的 std::sort 通常用 introsort(快排+堆排兜底),而非纯堆排。
- 对少于 ~32 个元素的数组,插入排序更快;标准库实现通常会切分处理
- 堆排序不稳定:相等元素的相对位置可能改变,比如用于结构体排序时要注意字段相等性
- 缓存不友好:
sift_down的跳转访问模式导致 CPU cache miss 高于归并或快排
如果你真需要手写堆排序,优先考虑复用 std::make_heap + std::pop_heap;手动实现只在教学、嵌入式无 STL 或定制比较逻辑时才值得投入。
# c++
# 排序算法
# 标准库
# less
# sort
# 结构体
# 插入排序
# int
# 循环
# 堆
# 算法
# 这是
# 升序
# 大堆
# 而非
# 不稳定
# 移到
# 复用
# 的是
# 不友好
# 也不
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
手机网站制作与建设方案,手机网站如何建设?
Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置
javascript中对象的定义、使用以及对象和原型链操作小结
黑客如何通过漏洞一步步攻陷网站服务器?
高端企业智能建站程序:SEO优化与响应式模板定制开发
Laravel辅助函数有哪些_Laravel Helpers常用助手函数大全
详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点
详解Huffman编码算法之Java实现
php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】
简单实现Android验证码
php结合redis实现高并发下的抢购、秒杀功能的实例
高端智能建站公司优选:品牌定制与SEO优化一站式服务
网站页面设计需要考虑到这些问题
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
如何用虚拟主机快速搭建网站?详细步骤解析
如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框
Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】
Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言
绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信
微信推文制作网站有哪些,怎么做微信推文,急?
如何破解联通资金短缺导致的基站建设难题?
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
Laravel如何获取当前登录用户信息_Laravel Auth门面使用与Session用户读取【技巧】
Laravel观察者模式如何使用_Laravel Model Observer配置
教学论文网站制作软件有哪些,写论文用什么软件
?
Windows10如何更改计算机工作组_Win10系统属性修改Workgroup
如何在阿里云域名上完成建站全流程?
微信小程序 闭包写法详细介绍
怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?
详解阿里云nginx服务器多站点的配置
油猴 教程,油猴搜脚本为什么会网页无法显示?
Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程
焦点电影公司作品,电影焦点结局是什么?
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
Laravel如何实现一对一模型关联?(Eloquent示例)
如何在服务器上配置二级域名建站?
如何快速生成凡客建站的专业级图册?
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
深圳网站制作公司好吗,在深圳找工作哪个网站最好啊?
谷歌Google入口永久地址_Google搜索引擎官网首页永久入口
如何挑选高效建站主机与优质域名?
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
原生JS实现图片轮播切换效果
Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南
JavaScript模板引擎Template.js使用详解
如何在万网利用已有域名快速建站?
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
如何快速生成专业多端适配建站电话?
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】

