[******] 堆排序
1. 题目描述 堆排序
import java.util.Arrays; public class HeapSort { public static void main(String[] args) { int [] array = new int[]{2,3,5,6,7,8,23,1,9}; array = heapSort(array); for (int i = 0; i < array.length; i++) { System.out.print(array[i]+" "); } } // 堆排序(HeapSort):移除位在第一个数据的根节点,并做最大堆调整的递归运算 public static int[] heapSort(int[] sourceArray) { // 对 arr 进行拷贝,不改变参数内容 int[] arr = Arrays.copyOf(sourceArray, sourceArray.length); int len = arr.length; // 建立最大堆 buildMaxHeap(arr, len); // 首尾元素交换,长度减一,尾部元素最大 for (int i = len - 1; i > 0; i--) { swap(arr, 0, i); len--; heapify(arr, 0, len); } return arr; } /** * 创建最大堆(Build-Max-Heap)的作用是将一个数组改造成一个最大堆,接受数组和堆大小两个参数, * Build-Max-Heap 将自下而上的调用 Max-Heapify 来改造数组,建立最大堆【注意从非叶子节点开始】。 * 因为 Max-Heapify 能够保证下标 i 的结点之后结点都满足最大堆的性质,所以自下而上的调用 Max-Heapify 能够在改造过程中保持这一性质。 */ private static void buildMaxHeap(int[] arr, int len) { // 非叶子节点开始 for (int i = (int) Math.floor(len / 2); i >= 0; i--) { heapify(arr, i, len); } } // 最大堆调整(Max Heapify):将堆的末端子节点作调整,使得子节点永远小于父节点 private static void heapify(int[] arr, int i, int len) { int left = 2 * i + 1; int right = 2 * i + 2; int largest = i; if (left < len && arr[left] > arr[largest]) { largest = left; } if (right < len && arr[right] > arr[largest]) { largest = right; } if (largest != i) {//保证下标 i 的结点之后结点都满足最大堆的性质 swap(arr, i, largest); heapify(arr, largest, len); } } private static void swap(int[] arr, int i, int j) { int temp = arr[i]; arr[i] = arr[j]; arr[j] = temp; } }