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

排序算法之堆排序详细解读(附带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 方法对数组进行排序。
    • 输出排序前和排序后的数组。

 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【比较】数据字节串/字串比较指令 (CMPSB/CMPSW),数据字节串/字串检索指令(SCASB/SCASW)的区别
  • 实战项目:俄罗斯方块(二)
  • 鸿蒙OpenHarmony、HarmonyOS、HarmonyOS NEXT的区别
  • 直播行业的未来:南昌络喆科技有限公司的创新无人直播项目!
  • The Power of Scale for Parameter-Efficient Prompt Tuning
  • Hive锁表、hive查询表是否被锁、hive解锁表
  • 数据结构之 “单链表“
  • MAC环境导出项目的目录结构
  • 【iOS】折叠cell
  • PG逻辑解码
  • 常见的性能测试方法!
  • 计算机毕业设计推荐-基于python的公司员工考勤管理系统
  • 全网最详细docker详解,从概念到实战一篇解决
  • 【 html+css 绚丽Loading 】000030 灵文闪烁符
  • 汽车免拆诊断案例 | 马自达CX-3无音频输出
  • Angular 响应式表单 基础例子
  • CAP理论的例子讲解
  • CSS3 变换
  • CSS相对定位
  • java取消线程实例
  • Laravel 实践之路: 数据库迁移与数据填充
  • LeetCode29.两数相除 JavaScript
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • Python学习笔记 字符串拼接
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • SpringBoot 实战 (三) | 配置文件详解
  • vuex 笔记整理
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 聚类分析——Kmeans
  • 深度学习中的信息论知识详解
  • 十年未变!安全,谁之责?(下)
  • 什么是Javascript函数节流?
  • 微信公众号开发小记——5.python微信红包
  • 新手搭建网站的主要流程
  • 学习Vue.js的五个小例子
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • # 利刃出鞘_Tomcat 核心原理解析(八)-- Tomcat 集群
  • #define、const、typedef的差别
  • (1)Nginx简介和安装教程
  • (k8s中)docker netty OOM问题记录
  • (附源码)springboot 房产中介系统 毕业设计 312341
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (规划)24届春招和25届暑假实习路线准备规划
  • (蓝桥杯每日一题)平方末尾及补充(常用的字符串函数功能)
  • (三)终结任务
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)Google的Objective-C编码规范
  • (转)Unity3DUnity3D在android下调试
  • (转)树状数组
  • *(长期更新)软考网络工程师学习笔记——Section 22 无线局域网
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net framework profiles /.net framework 配置
  • .NET 将混合了多个不同平台(Windows Mac Linux)的文件 目录的路径格式化成同一个平台下的路径
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • .NET开源、简单、实用的数据库文档生成工具