堆排序的用途很广泛,在面试中也是一个经常会被通过各种角度考到的点:

  1. 从1亿个数据里面挑选最大的k个数?
  2. 求无序数组的中位数,求第k大数?
  3. 等等。。。

堆排序的实现

分为两步:

  1. 构建堆
  2. 排序

1.首先是构建堆

1.1通过JDK工具类构建堆

构建堆可以自己实现,也可以通过JDk中相应的实现PriorityQueuePriorityQueue默认是最小堆,如果想要实现最大堆的话,我们可以在初始化时添加一个Comparator比较器,如:

PriorityQueue pq = new PriorityQueue(new Comparator() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });

何时选择最大堆?何时选择最小堆?
一般来说,当要对数组进行升序排序时,选择最大堆;反之,选择最小堆。

1.2 自己实现构建堆

代码一:

//摘抄自菜鸟教程:https://www.runoob.com/w3cnote/heap-sort.html
private void buildMaxHeap(int[] arr, int len) {
        for (int i = (int) Math.floor(len / 2); i >= 0; i--) {
            heapify(arr, i, len);
        }
    }

    private void heapify(int[] arr, int i, int len) {
        int left = 2 * i + 1;
        int right = 2 * i + 2;
        int largest = i;

        if (left < len && arr[left] > arr[largest]) {
            largest = left;
        }

        if (right < len && arr[right] > arr[largest]) {
            largest = right;
        }

        if (largest != i) {
            swap(arr, i, largest);
            heapify(arr, largest, len);
        }
    }

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

代码二:

static void buildSmallHeap(int[] a){
        for (int i = a.length/2; i >=0 ; i--) {
            sink(a,i,a.length);
        }
    }
    //参考priorityQueue中的方法shiftDown方法
    static void sink(int[] a,int k,int len){
        int key = a[k];
        int half = len>>>1;
        while (k<half){
            int child = (k<<1) + 1;//左孩子
            int c = a[child];
            int right = child + 1;//右孩子
            if(right < len && c > a[right])c = a[child = right];//右孩子小于左孩子,对child、c重新赋值
            if(key < a[child]) break;//父节点均小于左右孩子,直接结束
            a[k] = c;
            k = child;
        }
        a[k] = key;
    }

现在我们来分析一下构建堆的时间复杂度:
https://www.cnblogs.com/wongyi/p/7685061.html
https://www.zhihu.com/question/20729324