堆排序的基本思想是:将待排序序列构造成一个大顶堆,此时,整个序列的最大值就是堆顶的根节点。将其与末尾元素进行交换,此时末尾就为最大值。然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了
测试程序:
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){ // 先用j标识值最大的孩子 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; }
运行结果:
[5, 9, 30, 36, 41, 49, 56, 63, 69, 70]