欢迎访问宙启技术站
智能推送

在Java中实现一个堆排序算法的方法

发布时间:2023-09-17 20:57:14

堆排序是一种基于二叉堆数据结构的排序算法。它的主要思想是将待排序的序列构建成一个大顶堆(或小顶堆),然后将堆顶元素与末尾元素交换,将最大(或最小)元素移到末尾,再重新调整堆,直到整个序列有序。

具体实现堆排序的方法如下:

1. 构建堆:首先将待排序的序列看作是一个完全二叉树,从最后一个非叶子节点开始(索引为n/2-1),依次向上逐个调整节点,使得每个节点与其孩子节点满足堆的性质。这一步的目的是将无序序列转换为一个堆。

2. 调整堆:从最后一个非叶子节点开始,从左到右、从下到上依次遍历每个节点,对于每个节点,将其与左右孩子节点比较,如果存在比其大(或小)的孩子节点,则将该节点与其较大(或较小)的孩子节点交换位置,并继续向下调整被交换的子树,直到该节点与其孩子节点满足堆的性质。这一步的目的是将根节点与序列中最后一个元素交换位置,并维护堆的性质。

3. 重复步骤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);
        }
    }

    // 调整堆
    public 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 temp = arr[i];
            arr[i] = arr[largest];
            arr[largest] = temp;
            heapify(arr, n, largest);
        }
    }

    public static void main(String[] args) {
        int[] arr = {6, 5, 3, 1, 8, 7, 2, 4};
        heapSort(arr);
        System.out.println(Arrays.toString(arr));
    }
}

以上代码首先构建堆,然后通过交换堆顶元素与末尾元素的方式,使得最大值(或最小值)移到末尾,然后调整堆并重复交换操作,直到整个序列有序。运行代码可以得到排序后的结果:[1, 2, 3, 4, 5, 6, 7, 8]。

堆排序的时间复杂度为O(nlogn),其中n为序列长度。