当前位置: 首页 > news >正文

堆排序算法详解:原理、实现与C语言代码

堆排序(Heap Sort)是一种高效的排序算法,利用二叉堆数据结构实现。其核心思想是将待排序序列构造成一个大顶堆(或小顶堆),通过反复调整堆结构完成排序。下面从原理到实现进行详细解析。


一、核心概念:二叉堆

二叉堆是一种完全二叉树,满足以下性质:

  • 大顶堆:父节点值 ≥ 子节点值(用于升序排序)

  • 小顶堆:父节点值 ≤ 子节点值(用于降序排序)


二、堆排序步骤
  1. 初始建堆:将无序序列构建成大顶堆

  2. 堆排序:反复将堆顶元素与末尾交换,并调整堆

1. 初始建堆(Heapify)

从最后一个非叶子节点开始,自底向上调整堆结构。

关键公式(数组下标从0开始):

  • 节点 i 的左子节点:2i + 1

  • 节点 i 的右子节点:2i + 2

  • 最后一个非叶子节点:n/2 - 1

调整过程

  1. 比较当前节点与左右子节点

  2. 若子节点更大,则与最大子节点交换

  3. 递归调整被影响的子树

2. 堆排序流程
  1. 将堆顶元素(最大值)与末尾元素交换

  2. 堆大小减1,重新调整堆顶元素

  3. 重复直到堆大小为1


三、C语言完整实现
#include <stdio.h>// 交换元素
void swap(int* a, int* b) {int temp = *a;*a = *b;*b = temp;
}// 调整堆(大顶堆)
void heapify(int arr[], int n, int i) {int largest = i;         // 初始化最大值为根节点int left = 2 * i + 1;    // 左子节点下标int right = 2 * i + 2;   // 右子节点下标// 比较左子节点与根节点if (left < n && arr[left] > arr[largest])largest = left;// 比较右子节点与当前最大值if (right < n && arr[right] > arr[largest])largest = right;// 若最大值不是根节点,则交换并递归调整if (largest != i) {swap(&arr[i], &arr[largest]);heapify(arr, n, largest);  // 递归调整受影响子树}
}// 堆排序主函数
void heapSort(int arr[], int n) {// 初始建堆:从最后一个非叶子节点开始for (int i = n / 2 - 1; i >= 0; i--)heapify(arr, n, i);// 依次提取堆顶元素for (int i = n - 1; i > 0; i--) {swap(&arr[0], &arr[i]);  // 将堆顶移至末尾heapify(arr, i, 0);      // 调整剩余元素}
}// 测试代码
int main() {int arr[] = {12, 11, 13, 5, 6, 7};int n = sizeof(arr) / sizeof(arr[0]);printf("原始数组:\n");for (int i = 0; i < n; i++)printf("%d ", arr[i]);heapSort(arr, n);printf("\n排序后数组:\n");for (int i = 0; i < n; i++)printf("%d ", arr[i]);return 0;
}

四、算法分析
指标说明
时间复杂度O(n log n)建堆O(n),每次调整O(log n)
空间复杂度O(1)原地排序
稳定性不稳定交换可能改变相等元素顺序
适用场景大数据量排序内存受限时优于归并排序

五、关键点解析
  1. 为什么从n/2-1开始建堆?
    完全二叉树中,非叶子节点占总数一半,且最后一个非叶子节点的下标为n/2-1

  2. 为何堆排序不稳定?
    交换堆顶与末尾元素时,可能破坏相等元素的原始顺序(如[5, 5, 3])。

  3. 优化方向

    • 小规模数据用插入排序优化

    • 循环展开加速堆调整

    • 多线程并行处理子树调整

堆排序是高效排序算法的基石,也是优先级队列的核心实现。理解其原理对掌握高级数据结构至关重要。

http://www.lryc.cn/news/590083.html

相关文章:

  • 网络安全(初级)(Python实现sql自动化布尔盲注)
  • 牛客:HJ25 数据分类处理[华为机考][哈希][字符串]
  • python基础②-数据结构
  • 【DataWhale】快乐学习大模型 | 202507,Task02笔记
  • 牛客:HJ26 字符串排序[华为机考][map]
  • 3d max 图片(参考图)的导入
  • 设计模式—初识设计模式
  • Java大厂面试实录:从Spring Boot到AI大模型的深度技术拷问
  • iOS App 上架流程优化指南 工具组合与常见问题处理经验总结
  • C语言:第07天笔记
  • Ubuntu中man手册不全解决以及man手册中英文切换方法
  • pyJianYingDraft 在 import_srt 字幕添加花字效果
  • 海康线扫相机通过采集卡的取图设置
  • WSL2更新后Ubuntu 24.04打不开(终端卡住,没有输出)
  • 【中文核心期刊推荐】《激光与红外》
  • db.refresh()的重复使用和db.rollback()
  • 随机链表的复制数据结构oj题(CM11)
  • Python练习(4)Python参数传递的20道核心实战练习题(含答案与深度解析)(上)
  • BNN 技术详解:当神经网络只剩下 +1 和 -1
  • 《精华离散制造智能工厂三年规划》81页PPT
  • Git分支管理完全指南:从创建到合并与冲突解决
  • 关于redis各种类型在不同场景下的使用
  • 基于 Python/PHP/Node.js 的淘宝 API 商品数据抓取开发教程
  • django安装、跨域、缓存、令牌、路由、中间件等配置
  • .env文件的配置
  • 搭建云途YTM32B1MD1芯片VSCODE+GCC + Nijia + Cmake+Jlink开发环境
  • python的慈善捐赠平台管理信息系统
  • 将URL地址最后一段中文内容进行URL编码
  • Harmony-Next鸿蒙实战开发项目-仿小米商城App----V2
  • 【18】MFC入门到精通——MFC(VS2019)+ OpenCV 显示图片的3种方法