排序算法之堆排序详细解读(附带Java代码解读)

2024-08-28 14:04

本文主要是介绍排序算法之堆排序详细解读(附带Java代码解读),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

堆排序(Heap Sort)是一种基于比较的排序算法,它利用堆数据结构来排序元素。堆是一种特殊的完全二叉树,堆排序的基本思想是将数组构建成一个最大堆(或最小堆),然后通过交换根节点和堆的最后一个元素,将最大(或最小)元素移到数组的末尾。接着,调整堆,使其重新满足堆的性质,然后重复这一过程直到排序完成。

算法思想

  1. 构建最大堆:将无序数组构建成一个最大堆。最大堆的特性是每个节点的值都大于或等于其子节点的值。
  2. 提取最大元素:将堆顶(最大元素)与堆的最后一个元素交换,然后将堆的有效大小减小 1。对交换后的堆进行调整,以保持最大堆的性质。
  3. 重复步骤 2:直到堆的有效大小为 1,整个数组已经排序完成。

过程示例

假设有一个待排序的数组:[4, 10, 3, 5, 1]

步骤 1: 构建最大堆

将数组构建成最大堆:

  • 初始数组:[4, 10, 3, 5, 1]
  • 从最后一个非叶子节点开始向上调整:
    • 调整节点 10:[10, 5, 3, 4, 1]
    • 调整节点 4:[10, 5, 4, 3, 1]

步骤 2: 提取最大元素

将堆顶(最大元素 10)与堆的最后一个元素交换,然后调整堆:

  • 交换:[1, 5, 4, 3, 10]
  • 调整堆:[5, 3, 4, 1, 10]
  • 交换堆顶和最后一个元素后,堆变成:[5, 3, 4, 1],最大元素 10 已经放在正确位置

重复上述步骤:

  • 交换堆顶和最后一个元素:[1, 3, 4, 5, 10]
  • 调整堆:[4, 3, 1, 5, 10]
  • 交换堆顶和最后一个元素:[1, 3, 4, 5, 10]
  • 调整堆:[3, 1, 4, 5, 10]
  • 交换堆顶和最后一个元素:[1, 3, 4, 5, 10]
  • 调整堆:[1, 3, 4, 5, 10],最终数组为:[1, 3, 4, 5, 10]

算法复杂度

  • 时间复杂度:

    • 最坏情况: O(n log n)
    • 平均情况: O(n log n)
    • 最佳情况: O(n log n)
  • 空间复杂度: O(1) 堆排序是原地排序算法,不需要额外的存储空间。

优点

  1. 原地排序:只需要常数级别的额外空间。
  2. 时间复杂度优良:最坏情况时间复杂度为 O(n log n),适合大数据量的排序。

缺点

  1. 不稳定排序:相等元素的相对顺序可能会改变。
  2. 实现较复杂:相较于其他排序算法(如插入排序),堆排序的实现较复杂。

Java代码解读

public class HeapSort {// 主方法:执行堆排序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);}}// 调整堆的函数private 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};System.out.println("排序前的数组:");for (int num : arr) {System.out.print(num + " ");}System.out.println();heapSort(arr);System.out.println("排序后的数组:");for (int num : arr) {System.out.print(num + " ");}}
}

代码说明

  1. heapSort方法:

    • heapSort 方法首先构建最大堆,然后逐步将最大元素移到数组末尾,并调整堆。
  2. heapify方法:

    • heapify 方法调整堆以保持最大堆的性质。
    • 它检查节点的左子节点和右子节点,将最大元素移动到根节点,并递归地调整被替换子节点的堆。
  3. main方法:

    • 创建一个待排序的数组 arr
    • 调用 heapSort 方法对数组进行排序。
    • 输出排序前和排序后的数组。

 

这篇关于排序算法之堆排序详细解读(附带Java代码解读)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1114968

相关文章

javax.net.ssl.SSLHandshakeException:异常原因及解决方案

《javax.net.ssl.SSLHandshakeException:异常原因及解决方案》javax.net.ssl.SSLHandshakeException是一个SSL握手异常,通常在建立SS... 目录报错原因在程序中绕过服务器的安全验证注意点最后多说一句报错原因一般出现这种问题是因为目标服务器

CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比

《CSS中的Static、Relative、Absolute、Fixed、Sticky的应用与详细对比》CSS中的position属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布... css 中的 position 属性用于控制元素的定位方式,不同的定位方式会影响元素在页面中的布局和层叠关

Java实现删除文件中的指定内容

《Java实现删除文件中的指定内容》在日常开发中,经常需要对文本文件进行批量处理,其中,删除文件中指定内容是最常见的需求之一,下面我们就来看看如何使用java实现删除文件中的指定内容吧... 目录1. 项目背景详细介绍2. 项目需求详细介绍2.1 功能需求2.2 非功能需求3. 相关技术详细介绍3.1 Ja

springboot项目中整合高德地图的实践

《springboot项目中整合高德地图的实践》:本文主要介绍springboot项目中整合高德地图的实践,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一:高德开放平台的使用二:创建数据库(我是用的是mysql)三:Springboot所需的依赖(根据你的需求再

spring中的ImportSelector接口示例详解

《spring中的ImportSelector接口示例详解》Spring的ImportSelector接口用于动态选择配置类,实现条件化和模块化配置,关键方法selectImports根据注解信息返回... 目录一、核心作用二、关键方法三、扩展功能四、使用示例五、工作原理六、应用场景七、自定义实现Impor

SpringBoot3应用中集成和使用Spring Retry的实践记录

《SpringBoot3应用中集成和使用SpringRetry的实践记录》SpringRetry为SpringBoot3提供重试机制,支持注解和编程式两种方式,可配置重试策略与监听器,适用于临时性故... 目录1. 简介2. 环境准备3. 使用方式3.1 注解方式 基础使用自定义重试策略失败恢复机制注意事项

在Windows上使用qemu安装ubuntu24.04服务器的详细指南

《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

SpringBoot整合Flowable实现工作流的详细流程

《SpringBoot整合Flowable实现工作流的详细流程》Flowable是一个使用Java编写的轻量级业务流程引擎,Flowable流程引擎可用于部署BPMN2.0流程定义,创建这些流程定义的... 目录1、流程引擎介绍2、创建项目3、画流程图4、开发接口4.1 Java 类梳理4.2 查看流程图4

一文详解如何在idea中快速搭建一个Spring Boot项目

《一文详解如何在idea中快速搭建一个SpringBoot项目》IntelliJIDEA作为Java开发者的‌首选IDE‌,深度集成SpringBoot支持,可一键生成项目骨架、智能配置依赖,这篇文... 目录前言1、创建项目名称2、勾选需要的依赖3、在setting中检查maven4、编写数据源5、开启热

SQL Server数据库死锁处理超详细攻略

《SQLServer数据库死锁处理超详细攻略》SQLServer作为主流数据库管理系统,在高并发场景下可能面临死锁问题,影响系统性能和稳定性,这篇文章主要给大家介绍了关于SQLServer数据库死... 目录一、引言二、查询 Sqlserver 中造成死锁的 SPID三、用内置函数查询执行信息1. sp_w