Java实现堆排序算法

1. 堆排序原理图解

堆排序是一种基于二叉堆(通常使用最大堆)的排序算法。其核心思想是利用堆的性质(父节点的值大于或等于子节点的值)来高效地进行排序。堆排序分为两个主要阶段:建堆和排序。

堆排序步骤:

  1. 建堆:
  • 将无序数组构建成一个最大堆。

  • 从最后一个非叶子节点开始,逐个调整节点,使其满足堆的性质。

  1. 排序:
  • 将堆顶元素(最大值)与堆的最后一个元素交换。

  • 缩小堆的范围,重新调整堆,使其满足最大堆的性质。

  • 重复上述过程,直到堆的大小为1。

图解示例:

假设数组为 `4, 10, 3, 5, 1`。

  1. 初始状态:`4, 10, 3, 5, 1`

  2. 建堆:

  • 调整节点,构建最大堆:`10, 5, 3, 4, 1`
  1. 排序过程:
  • 将堆顶元素(10)与最后一个元素(1)交换:`1, 5, 3, 4, 10`

  • 调整剩余的堆(`1, 5, 3, 4`),使其满足最大堆的性质:`5, 4, 3, 1`

  • 将堆顶元素(5)与最后一个元素(1)交换:`1, 4, 3, 5, 10`

  • 调整剩余的堆(`1, 4, 3`),使其满足最大堆的性质:`4, 1, 3`

  • 将堆顶元素(4)与最后一个元素(3)交换:`3, 1, 4, 5, 10`

  • 调整剩余的堆(`3, 1`),使其满足最大堆的性质:`3, 1`

  • 将堆顶元素(3)与最后一个元素(1)交换:`1, 3, 4, 5, 10`

  1. **最终结果**:`1, 3, 4, 5, 10`

  2. Java代码实现及注释

```java

import java.util.Arrays;

public class HeapSort {

public static void main(String\[\] args) {

int\[\] array = {4, 10, 3, 5, 1};

heapSort(array);

System.out.println("排序后的数组:");

System.out.println(Arrays.toString(array));

}

// 堆排序主方法

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 = arr0;

arr0 = arri;

arri = temp;

// 调整剩余的堆

heapify(arr, i, 0);

}

}

// 调整堆的方法

private static void heapify(int\[\] arr, int heapSize, int rootIndex) {

int largest = rootIndex; // 假设根节点是最大的

int leftChild = 2 * rootIndex + 1; // 左子节点

int rightChild = 2 * rootIndex + 2; // 右子节点

// 如果左子节点大于根节点

if (leftChild < heapSize && arrleftChild > arrlargest) {

largest = leftChild;

}

// 如果右子节点大于当前最大的节点

if (rightChild < heapSize && arrrightChild > arrlargest) {

largest = rightChild;

}

// 如果最大的节点不是根节点,交换它们

if (largest != rootIndex) {

int temp = arrrootIndex;

arrrootIndex = arrlargest;

arrlargest = temp;

// 递归调整子树

heapify(arr, heapSize, largest);

}

}

}

```

3. 代码说明

  1. 建堆:
  • 从最后一个非叶子节点开始,逐个调整节点,使其满足最大堆的性质。

  • 使用 `heapify` 方法调整节点。

  1. 排序:
  • 将堆顶元素(最大值)与堆的最后一个元素交换。

  • 缩小堆的范围,重新调整堆,使其满足最大堆的性质。

  • 重复上述过程,直到堆的大小为1。

  1. 时间复杂度:
  • **最坏情况**:`O(n log n)`。

  • **平均情况**:`O(n log n)`。

  • **最好情况**:`O(n log n)`。

  1. 空间复杂度:
  • `O(1)`,因为堆排序是原地排序算法,不需要额外的存储空间。
  1. 稳定性:
  • 堆排序是**不稳定的**,因为交换操作可能改变相同值元素的相对顺序。

4. 应用场景

  1. 大规模数据排序:
  • 堆排序的时间复杂度为 `O(n log n)`,适合对大规模数据进行排序。
  1. 优先队列实现:
  • 堆排序的核心思想可以用于实现优先队列,例如在任务调度中。
  1. 教学和演示:
  • 堆排序的实现清晰,适合用于教学和算法演示。

5. 总结

堆排序是一种高效的排序算法,基于二叉堆的性质实现。它的时间复杂度稳定在 `O(n log n)`,并且是原地排序算法,不需要额外的存储空间。然而,堆排序是不稳定的,因此在需要保持相同值元素相对顺序的场景中不适用。在实际应用中,堆排序常用于大规模数据排序和优先队列的实现。

相关推荐
龙亘川3 分钟前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵5 分钟前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
秋天的怀念_David31 分钟前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas10044 分钟前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
Pniubi1 小时前
力扣283移动零(双指针法)
算法·leetcode·职场和发展
hhb_6181 小时前
大模型落地三重优化实战
人工智能·算法·机器学习
云和数据.ChenGuang1 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
niucloud-admin1 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质2 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain3762 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis