Heap Sort

堆是一种数据结构,本质是存放在数组中的完全二叉树。如图,完全二叉树存放在数组中为:[10, 7, 2, 5, 1]。该数组的特点为:对于第i个数,其左孩子为第2×i+1个,右孩子为2×i+2个。

堆分为大根堆和小根堆,大根堆的任意节点的值都大于其左孩子和右孩子节点的值;小根堆的任意节点都小于其左孩子和右孩子节点的值。

堆排序主要分为两步:
1、建堆,即把一个无序数组构建成大/小根堆;
2、把堆的根节点和最后一个节点的值替换;把前n-1个节点重新构建成大/小根堆
3、把堆的根节点和最后一个节点的值替换;把前n-2个节点重新构建成大/小根堆
4、...
剩余的循环步骤中,每一次都挑出最大/小的值,放在数组最后位置,然后再将前面未排序的值重新建堆。

public class HeapSort {

    public void hsort(int[] arr) {
    if (arr == null || arr.length == 0)
        return;

    int n = arr.length;

    // 把arr调整为大顶堆
    for (int i = (n >> 1) - 1; i >= 0; --i)
        adjust(arr, i, n);

    for (int i = n - 1; i > 0; --i) {
            swap(arr, 0, i); // 把arr的堆顶换到最后
            adjust(arr, 0, i); // 把arr中0-i位置的堆调整为大顶堆
        }
    }

    // 确保以第i个节点为根节点,长度为n的堆为大顶堆
    private void adjust(int[] arr, int i, int n) {
        int left = (i << 1) + 1;
        int right = (i << 1) + 2;
        int max = i;

        if (left < n && arr[left] > arr[max]) max = left;
        if (right < n && arr[right] > arr[max]) max = right;
        if (max != i) {
            swap(arr, i, max);
            adjust(arr, max, n);
        }
    }

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

堆的最好最坏平均时间复杂度都为O(nlogn),为非稳定排序

posted @ 2021-11-19 17:58  moon_orange  阅读(25)  评论(0编辑  收藏  举报