堆排序的基本思想
将待排序序列构造成一个大顶堆,此时,整个序列的最大值是堆顶的根节点。将其与末尾元素进行交换,此时末尾为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列。
代码实现如下
public class HeapSort {
public static void main(String[] args) {
int[] arr = new int[10];
Random rd = new Random();
for (int i = 0; i < arr.length; i++) {
arr[i] = rd.nextInt(100);
}
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
/**
* 实现堆排序
*
* @param arr
*/
private static void heapSort(int[] arr) {
int n = arr.length - 1;
// 从第一个非叶子节点开始,把大值往父节点调整
for (int i = (n - 1) / 2; i >= 0; --i) {
adjust(arr, i, arr.length);
}
for (int i = n; i >= 0; --i) {
//0 <=> i 它们的值进行交换
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
//再继续进行堆的调整 adjust
adjust(arr,0,i);
}
}
/**
* 堆的调整函数,把每一个节点,和其左右孩子节点的最大值放到当前节点处
*
* @param arr
* @param i
* @param length
*/
private static void adjust(int[] arr, int i, int length) {
int val=arr[i];
for (int j=2*i+1;j<length;j=2*j+1){
if (j+1<length&&arr[j+1]>arr[j]){
j++;
}
if (arr[j]>val){
arr[i]=arr[j];
i=j;
}else {
break;
}
arr[i]=val;
}
}