本文已参与「新人创作礼」活动,一起开启掘金创作之路。
堆的前置知识
对于堆的学习,我前面写过一些关于大根堆和小根堆的实现
大家可以先看看,了解一下。
堆排序思路
对于这个思路我们可以这样想,我们每一次堆排序,最上面的那个一定是整个树里面最大的或者最小的。
那我们这个时候和最后一个元素交换,交换之后,我们就不再过问这个元素,并且我们把交换之后最上面的树放到它应该在的地方。以此往复,这样我们是不是可以排好序了。
代码
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;
}
上面这段代码就是变形金刚的螺丝,也是必不可少的一环,是一个交换函数。
以上就是堆排序的全部了。