堆排序是比较稳定的排序方式,且时间复杂度为 nlogn;
1.先将数组元素下沉,形成最大堆,此时堆顶元素就是最大的元素,它应当在数组最后
2.将堆顶元素与最后一个元素交换
3.保持最后一个元素不动,下沉堆顶元素
具体代码如下:
public class Test {
public static void heapSort(int[] arr){
// 每个元素下沉,得到最大堆
for (int i = 0; i < arr.length; i++) {
siftDown(arr,i,arr.length);
}
// 将最大堆的元素从最后一个叶子结点开始 先于堆顶节点交换,然后将对定节点下沉到相应位置
for (int i = arr.length - 1; i > 0; i--) {
swap(arr,0,i);
siftDown(arr,0,i);
}
}
// 下沉元素
private static void siftDown(int[] arr, int i, int length) {
while(2 * i + 1 < length){
int j = 2 * i + 1;
if(j + 1 < length && arr[j + 1] > arr[j]){
j = j + 1;
}
if(arr[i] > arr[j]){
break;
}else{
swap(arr,i,j);
i = j;
}
}
}
private static void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void main(String[] args) {
int[] arr = new int[100000];
ThreadLocalRandom random = ThreadLocalRandom.current();
for (int i = 0; i < 100000; i++) {
arr[i] = random.nextInt(0,Integer.MAX_VALUE);
}
long t1 = System.nanoTime();
heapSort(arr);
long t2 = System.nanoTime();
System.out.println((t2 - t1) / 1000000);
}
}