Java编程入门,堆排序(Heap Sort)怎么做?

Java编程入门,堆排序(Heap Sort)怎么做?
最新回答
旧梦时光机丶

2026-10-17 22:53:50

堆排序(Heap Sort)是一种基于二叉堆数据结构的比较排序算法,其核心步骤包括构建堆和反复调整堆结构。以下是Java实现的详细说明:

1. 算法步骤
  1. 构建大顶堆

    从最后一个非叶子节点(索引为length/2 - 1)开始,自底向上调整每个子树,使其满足大顶堆性质(父节点 ≥ 子节点)。

    关键操作:adjustHeap()方法负责调整以当前节点为根的子树。

  2. 交换堆顶与末尾元素

    将堆顶元素(最大值)与当前无序区的末尾元素交换,此时末尾元素归入有序区。

    调整剩余无序区,使其重新成为大顶堆。

  3. 重复调整

    每次交换后,无序区长度减1,直到所有元素有序。

2. Java代码实现import java.util.Arrays;public class HeapSort { public static void main(String[] args) { int[] array = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48}; heapSort(array); System.out.println(Arrays.toString(array)); // 输出排序后的数组 } / * 堆排序主方法 */ public static void heapSort(int[] array) { if (array == null || array.length <= 1) { return; } int length = array.length; // 1. 构建大顶堆 for (int i = length / 2 - 1; i >= 0; i--) { adjustHeap(array, i, length); } // 2. 交换堆顶与末尾元素,并调整堆 for (int j = length - 1; j > 0; j--) { swap(array, 0, j); // 交换 adjustHeap(array, 0, j); // 调整剩余无序区 } } / * 调整大顶堆(从节点i开始,调整长度为length的子树) */ private static void adjustHeap(int[] array, int i, int length) { int temp = array[i]; // 保存当前节点值 for (int k = 2 * i + 1; k < length; k = 2 * k + 1) { // 从左子节点开始 // 选择较大的子节点 if (k + 1 < length && array[k] < array[k + 1]) { k++; } // 若子节点大于父节点,上移子节点 if (array[k] > temp) { array[i] = array[k]; i = k; // 继续向下调整 } else { break; } } array[i] = temp; // 放置temp到正确位置 } / * 交换数组中两个元素的位置 */ private static void swap(int[] array, int a, int b) { int temp = array[a]; array[a] = array[b]; array[b] = temp; }}3. 关键点解析
  • 大顶堆性质:父节点值 ≥ 子节点值,确保堆顶为最大值。
  • 调整堆的逻辑:

    从节点i的左子节点(2i+1)开始比较,若右子节点(2i+2)更大则选择右子节点。

    若子节点值大于当前节点值,则上移子节点,并继续向下调整。

  • 时间复杂度:

    构建堆:O(n)

    每次调整堆:O(log n),共需调整n-1次 → 总复杂度:O(n log n)

  • 空间复杂度:O(1)(原地排序)。
4. 动图演示

(动图展示了堆排序的构建堆、交换和调整过程)5. 常见问题
  • 为什么从length/2 - 1开始构建堆?因为叶子节点无需调整,最后一个非叶子节点的索引为n/2 - 1(完全二叉树性质)。
  • 与快速排序对比:堆排序最坏情况下仍为O(n log n),但常数因子较大,实际性能略逊于快速排序。

通过以上步骤和代码,你可以清晰理解堆排序的实现原理。建议手动模拟小规模数据(如[4, 10, 3, 5, 1])的排序过程以加深理解。