堆排序

87 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

堆的前置知识

对于堆的学习,我前面写过一些关于大根堆和小根堆的实现

大堆和小堆的实现 - 掘金 (juejin.cn)

大家可以先看看,了解一下。

堆排序思路

对于这个思路我们可以这样想,我们每一次堆排序,最上面的那个一定是整个树里面最大的或者最小的。

那我们这个时候和最后一个元素交换,交换之后,我们就不再过问这个元素,并且我们把交换之后最上面的树放到它应该在的地方。以此往复,这样我们是不是可以排好序了。

代码

public static void heapSort(int[] arr) {
    if (arr == null || arr.length < 2) {
        return;
    }
    for(int i = arr.length - 1 ;i >= 0 ;i--){
        heapFy(arr , i , arr.length);
    }
    for(int i = 0;i<arr.length;i++){
        swap(arr , 0 , arr.length - 1 - i);
        heapFy(arr , 0 , arr.length - i - 1);
    }
}

上面这段代码的重要性就在于调用了其他的代码,他就像是变形金刚的外壳,我们第一次堆排列让杂乱无章的数据变成大根堆的样子,好让后面的循环交换。

后面的训话那就是交换第一个和最后一个,然后再重新排列

public static void heapFy(int[] arr , int index , int size){
    int child = index * 2 + 1;
    while(child < size){
        if(child + 1 < size && arr[child] < arr[child + 1]){
            child++;
        }
        if(arr[index] < arr[child]){
            swap(arr , index , child);
            index = child;
            child = index * 2 + 1;
        }else{
            break;
        }
    }
}

上面的这段代码就像是变形金刚的能量来源,堆排列的实现,都是他的功劳,要不然变形金刚就是一堆的废铁。这也是普通的从上到下的堆排列,比起从下到上的堆排列,这个的时间复杂度更好。

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

上面这段代码就是变形金刚的螺丝,也是必不可少的一环,是一个交换函数。

以上就是堆排序的全部了。