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

Java实现堆排序算法详解及优化

引言

堆排序(Heap Sort)是一种基于堆数据结构的比较排序算法。它具有良好的时间复杂度特性,在许多实际应用中表现出色。本文将详细讲解如何使用Java实现堆排序算法,并结合图解和实例代码,帮助您全面理解这一高级排序算法。同时,我们还将探讨堆排序的优化方法,以进一步提高其性能。

堆排序算法的原理

堆排序通过将数组构建成一个最大堆,然后重复地将堆顶元素与末尾元素交换,并缩小堆的范围,重新调整堆结构来实现排序。

算法步骤

  1. 构建最大堆:将数组构建成一个最大堆。
  2. 交换并调整堆:将堆顶元素与末尾元素交换,缩小堆的范围,并调整堆结构,直到整个数组有序。

图解堆排序

为了更清晰地展示堆排序的过程,以下使用一个简单示例并分步骤图解:

初始数组: 4, 10, 3, 5, 1
构建最大堆: 10, 5, 3, 4, 1
交换堆顶和末尾元素: 1, 5, 3, 4, 10
调整堆: 5, 4, 3, 1, 10
交换堆顶和末尾元素: 1, 4, 3, 5, 10
调整堆: 4, 1, 3, 5, 10
交换堆顶和末尾元素: 1, 3, 4, 5, 10
调整堆: 3, 1, 4, 5, 10
交换堆顶和末尾元素: 1, 3, 4, 5, 10
最终排序结果: 1, 3, 4, 5, 10

Java实现堆排序

public class HeapSort {/*** 实现堆排序算法* @param arr 待排序的数组*/public static void heapSort(int[] arr) {int n = arr.length;// 构建最大堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 一个一个从堆顶取出元素for (int i = n - 1; i >= 0; i--) {// 交换堆顶和末尾元素int temp = arr[0];arr[0] = arr[i];arr[i] = temp;// 调整堆heapify(arr, i, 0);}}/*** 调整堆的方法* @param arr 待调整的数组* @param n 数组大小* @param i 根节点索引*/public static 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) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;// 递归调整受影响的子树heapify(arr, n, largest);}}public static void main(String[] args) {// 初始化数组int[] arr = {4, 10, 3, 5, 1};// 调用堆排序方法heapSort(arr);// 输出排序后的数组System.out.println("排序后的数组:");for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " ");}}
}

堆排序的优化方法

使用更小的辅助空间

堆排序是原地排序算法,但在实现过程中可以进一步优化,以减少递归调用的栈空间消耗。

图解优化后的堆排序

数组: 4, 10, 3, 5, 1
构建最大堆
调整堆的过程
交换并调整

Java实现优化后的堆排序

public class OptimizedHeapSort {/*** 实现优化后的堆排序算法* @param arr 待排序的数组*/public static void heapSort(int[] arr) {int n = arr.length;// 构建最大堆for (int i = n / 2 - 1; i >= 0; i--) {heapify(arr, n, i);}// 一个一个从堆顶取出元素for (int i = n - 1; i >= 0; i--) {// 交换堆顶和末尾元素int temp = arr[0];arr[0] = arr[i];arr[i] = temp;// 调整堆heapify(arr, i, 0);}}/*** 调整堆的方法* @param arr 待调整的数组* @param n 数组大小* @param i 根节点索引*/public static void heapify(int[] arr, int n, int i) {while (true) {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) {int swap = arr[i];arr[i] = arr[largest];arr[largest] = swap;// 更新根节点索引i = largest;} else {break;}}}public static void main(String[] args) {// 初始化数组int[] arr = {4, 10, 3, 5, 1};// 调用优化后的堆排序方法heapSort(arr);// 输出排序后的数组System.out.println("排序后的数组:");for (int i = 0; i < arr.length; i++) {System.out.print(arr[i] + " ");}}
}

结论

通过上述讲解和实例代码,我们详细展示了如何在Java中实现堆排序算法,并结合图解说明了其工作原理。同时,我们探讨了堆排序的优化方法,包括使用更小的辅助空间,以提高其性能。

希望这篇博客对您有所帮助!记得关注、点赞和收藏哦,以便随时查阅更多优质内容!


如果您觉得这篇文章对您有帮助,请关注我的CSDN博客,点赞并收藏这篇文章,您的支持是我持续创作的动力!


相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • JavaWeb(三:JDBC 与 MVC)
  • iOS热门面试题(四)
  • ARM学习(29)NXP 双coreMCU IMX1160学习----NorFlash 启动引脚选择
  • gin源码分析
  • fortran简单排序算法,对一维、二维矩阵进行正序或倒序排序
  • 【深度学习】PyTorch深度学习笔记02-线性模型
  • 百度安全大模型智能体实践入选信通院“安全守卫者计划”优秀案例
  • 专业条码二维码扫描设备和手机二维码扫描软件的区别?
  • 【Java--数据结构】栈:不仅仅是数据存储,它是编程的艺术
  • Docker 容器出现 IP 冲突
  • 深度加速器 为游戏而生
  • 【ARM】CCI缓存一致性整理
  • [论文笔记]RAPTOR: RECURSIVE ABSTRACTIVE PROCESSING FOR TREE-ORGANIZED RETRIEVAL
  • 【LeetCode】2187. 完成旅途的最少时间
  • 基于Python/MATLAB长时间序列遥感数据处理及在全球变化、植被物候提取、植被变绿与生态系统固碳分析、生物量估算与趋势分析应用
  • [微信小程序] 使用ES6特性Class后出现编译异常
  • css选择器
  • JS题目及答案整理
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • vue 配置sass、scss全局变量
  • 基于 Ueditor 的现代化编辑器 Neditor 1.5.4 发布
  • 类orAPI - 收藏集 - 掘金
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 悄悄地说一个bug
  • 深入浅出webpack学习(1)--核心概念
  • 微信公众号开发小记——5.python微信红包
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 用mpvue开发微信小程序
  • 用简单代码看卷积组块发展
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • # 达梦数据库知识点
  • #pragma预处理命令
  • #QT(QCharts绘制曲线)
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
  • (C++17) std算法之执行策略 execution
  • (ZT)出版业改革:该死的死,该生的生
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (九十四)函数和二维数组
  • (已解决)报错:Could not load the Qt platform plugin “xcb“
  • (转)linux 命令大全
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • ./configure,make,make install的作用
  • .DFS.
  • .gitignore文件—git忽略文件
  • .NET 中让 Task 支持带超时的异步等待
  • .Net--CLS,CTS,CLI,BCL,FCL
  • .NET教程 - 字符串 编码 正则表达式(String Encoding Regular Express)
  • ::前边啥也没有
  • @EnableAsync和@Async开始异步任务支持
  • @基于大模型的旅游路线推荐方案
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [ 蓝桥杯Web真题 ]-布局切换
  • [001-03-007].第07节:Redis中的管道