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

经典排序算法解析:归并与堆排序实战

一、今天学习目标

  1. 归并排序(分治法经典,稳定排序)
  2. 堆排序(利用堆结构实现,原地排序)
  3. 完整可运行代码
  4. 复杂度与适用场景总结

二、归并排序(Merge Sort)

核心思想:分而治之

  1. 把数组不断二分,直到每组只有 1 个元素
  2. 再把两个有序子数组合并成一个大的有序数组
  3. 递归完成

特点:

  • 稳定排序
  • 时间复杂度:O(n log n)
  • 空间复杂度:O(n)(需要临时数组)
// 合并两个有序区间 [l..mid] 和 [mid+1..r] void merge(int arr[], int l, int mid, int r) { int i = l, j = mid + 1, k = 0; int tmp[r - l + 1]; while (i <= mid && j <= r) { if (arr[i] <= arr[j]) tmp[k++] = arr[i++]; else tmp[k++] = arr[j++]; } while (i <= mid) tmp[k++] = arr[i++]; while (j <= r) tmp[k++] = arr[j++]; // 拷贝回原数组 for (i = l, k = 0; i <= r; i++, k++) arr[i] = tmp[k]; } // 归并排序递归 void mergeSort(int arr[], int l, int r) { if (l < r) { int mid = (l + r) / 2; mergeSort(arr, l, mid); mergeSort(arr, mid + 1, r); merge(arr, l, mid, r); } }

三、堆排序(Heap Sort)

核心思想:利用大顶堆

  1. 把数组构建成大顶堆
  2. 堆顶(最大值)与最后一个元素交换
  3. 堆大小减 1,重新调整堆
  4. 重复直到完成排序

特点:

  • 不稳定排序
  • 时间复杂度:O(n log n)
  • 空间复杂度:O(1)原地排序
void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; } // 下沉调整(大顶堆) void siftDown(int arr[], int n, int i) { while (1) { int maxPos = i; int left = 2 * i + 1; int right = 2 * i + 2; if (left < n && arr[left] > arr[maxPos]) maxPos = left; if (right < n && arr[right] > arr[maxPos]) maxPos = right; if (maxPos == i) break; swap(&arr[i], &arr[maxPos]); i = maxPos; } } // 堆排序 void heapSort(int arr[], int n) { // 建堆 for (int i = n / 2 - 1; i >= 0; i--) siftDown(arr, n, i); // 依次取堆顶 for (int i = n - 1; i > 0; i--) { swap(&arr[0], &arr[i]); siftDown(arr, i, 0); } }

四、完整测试代码

#include <stdio.h> // 上面所有函数放这里 void printArr(int arr[], int n) { for (int i = 0; i < n; i++) printf("%d ", arr[i]); printf("\n"); } int main() { int arr1[] = {6, 1, 8, 3, 5, 2, 7, 4}; int n = sizeof(arr1) / sizeof(arr1[0]); printf("原数组:"); printArr(arr1, n); // 归并排序 int arr2[8]; for (int i = 0; i < n; i++) arr2[i] = arr1[i]; mergeSort(arr2, 0, n - 1); printf("归并排序:"); printArr(arr2, n); // 堆排序 int arr3[8]; for (int i = 0; i < n; i++) arr3[i] = arr1[i]; heapSort(arr3, n); printf("堆排序:"); printArr(arr3, n); return 0; }

运行结果:

原数组:6 1 8 3 5 2 7 4 归并排序:1 2 3 4 5 6 7 8 堆排序:1 2 3 4 5 6 7 8

五、O (n log n) 排序对比

表格

排序时间复杂度空间稳定性特点
快排O(nlogn)O(logn)不稳定实际最快
归并O(nlogn)O(n)稳定外部排序常用
堆排O(nlogn)O(1)不稳定省内存

六、今日小练习

对数组{9, 4, 2, 7, 1, 6, 8, 3, 5}分别使用归并排序、堆排序并输出结果。

http://www.jsqmd.com/news/661950/

相关文章:

  • SITS2026发布在即:3大颠覆性AGI演进路径、5项硬性技术阈值与2026落地倒计时
  • 保姆级教程:手把手教你为Exynos 4412开发板移植U-Boot(附完整源码修改清单)
  • c++怎么将程序的私有配置信息加密保存为带头校验的加密二进制dat【详解】
  • Spring AI记忆持久化避坑指南:MySQL表设计优化与性能调优
  • 前端工程:CI/CD 的最佳实践
  • Multisim仿真:从74LS47译码器到数码管动态数显
  • Pixel Aurora Engine 构建数字人素材库:快速生成多样化人物肖像与表情
  • 有赞转港主板上市 白鸦:我终于意识到敲钟是很有意义的事
  • 系统恢复利器Rescuezilla:从数据灾难中拯救你的电脑
  • 重庆力冠衡器:大安地磅批发厂家 - LYL仔仔
  • 终极QtScrcpy键鼠映射配置指南:从零到精通的完整教程
  • 前端 API 设计的 RESTful API 高级实践:从理论到实战
  • 终极指南:用Playnite打造你的专属游戏库界面,告别千篇一律的启动器
  • 维普和知网AIGC检测有什么区别?不同平台降AI策略全解读
  • OpenSRE:开源框架集成 40 多种工具,助力 AI SRE 智能体应对生产事件
  • QuickRecorder:免费macOS录屏神器的终极完整指南
  • 告别RTOS:用时间片轮询在裸机上实现“伪多任务”
  • 2026年当下温州梦幻婚礼酒店测评:瑞锦大酒店一站式服务深度解析 - 2026年企业推荐榜
  • 【限时解禁】SITS2026白皮书技术附录首曝:7类AGI基准测试用例、37项性能指标定义及实测误差边界
  • 一文搞懂BBU:从原理到运维的实战指南
  • SQL优化SQL关联查询中的排序字段_减少临时空间占用与内存开销
  • 浏览器音乐解锁神器:3分钟搞定所有加密音乐格式
  • AGI透明度革命(2024全球仅7家机构验证通过的XAI评估协议)
  • 暗黑破坏神2存档编辑器:5步轻松修改角色属性和物品的终极指南
  • 5G NR上行控制信息复用:PUSCH信道上的UCI资源映射实战解析
  • 【2026年最新600套毕设项目分享】网络小说微信小程序(30095)
  • 宏基AS6530笔记本时序解析:从G3到S0的硬件启动密码
  • 避开C++位运算的坑:我用bitset重构PRESENT加密算法的密钥扩展与P置换
  • STM32CubeIDE实战:用HAL库搞定DS18B20和DHT11温湿度采集(附完整工程)
  • 深入对比Vivado FFT IP核的流水线与Burst IO架构:如何根据你的采样率做选择?