排序步骤
- 将长度为n的数组转化为大小顶堆
- 将第一个数沉底到最后
- 维护剩余数字的大小顶堆
- 重复 2 3 步n-1次
代码
转化顶堆代码
public static void adjustHeap(int[] arr, int root, int length){
int temp = arr[root];
for (int i = root*2+1; i < length; i = i*2+1) {
if(i+1 < length && arr[i] < arr[i+1]){
i++;
}
if(temp < arr[i]){
arr[root] = arr[i];
root = i;
}else{
break;
}
}
arr[root] = temp;
}
排序代码
public static void sort(int[] arr){
for (int i = arr.length/2 - 1; i >= 0; i--) {
adjustHeap(arr, i, arr.length);
}
int temp;
for (int i = arr.length-1; i > 0; i--) {
temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
adjustHeap(arr, 0, i);
}
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
测试
@org.junit.jupiter.api.Test
public void testHeap(){
int[] array = {4, 1, 3, 6, 8, 1};
HeapSort.sort(array);
}
结果
![堆排序结果](https://i-blog.csdnimg.cn/blog_migrate/e82c5381d5d226c364dc7e01c5768923.png)
注意
- 堆排序时间复杂度在创建堆时为O(n),排序时为O(nlogn)(需要排序n-1个,每次在堆中寻找一个位置,即logn)
- 堆排序为不稳定排序