堆排序

84 阅读2分钟

1. main 方法

  • 首先创建一个整数数组 arr 并初始化。
  • 通过 for 循环调用 heapInsert 方法,将数组转换为最大堆。
  • heapSize 表示堆的大小,初始为数组的长度。
  • 交换堆顶元素(最大值)和堆的最后一个元素,然后将堆的大小减 1。
  • 进入 while 循环,每次调用 heapPify 方法调整堆,再交换堆顶元素和当前堆的最后一个元素,直到堆的大小为 0。
  • 最后遍历排序好的数组并打印。

2. heapInsert 方法

  • 该方法用于将元素插入到堆中,并保持最大堆的性质。
  • 当当前元素 arr[i] 大于其父节点 arr[(i - 1) / 2] 时,交换它们的位置,并更新 i 为其父节点的索引,继续向上比较。

3. heapPify 方法

  • 该方法用于调整堆,使其保持最大堆的性质。
  • 首先计算当前节点的左子节点索引 left
  • 若右子节点存在且大于左子节点,则 largest 为右子节点的索引,否则为左子节点的索引。
  • 若 larg 对应的元素小于当前节点,则无需调整,跳出循环。
  • 否则交换 largest 和当前节点的位置,并更新 i 为 largest,继续向下调整。
public class HeapSort {
    public static void main(String[] args) {
        int[] arr = new int[]{4,7,2,44,2,67};

        for (int i = 0; i < arr.length; i++) {
            heapInsert(arr, i);
        }
        int heapSize = arr.length;
        swap(arr, 0, --heapSize);
        while (heapSize > 0) {
            heapPify(arr, 0, heapSize);
            swap(arr, 0, --heapSize);
        }
        for (int i : arr) {
            System.out.print(i + ",");
        }
    }

    public static void heapInsert(int[] arr, int i) {

        while (arr[i] > arr[(i - 1) / 2]) {
            swap(arr, i, (i - 1) / 2);
            i = (i - 1) / 2;
        }

    }

    public static void heapPify(int[] arr, int i, int heapSize) {

        int left = 2 * i + 1;
        while (left < heapSize) {

            int right = left + 1;
            int largest;
            if (right < heapSize && arr[right] > arr[left]) {
                largest = right;
            } else {
                largest = left;
            }
            if (arr[largest] < arr[i]) {
                break;
            }
            swap(arr, largest, i);
            i = largest;
            left = 2 * i + 1;
        }


    }

    public static void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}