堆排序
说明:使用数组保存堆结构,数组第0个元素不使用。
假设当前节点为i,当前节点父节点i/2,左孩子节点为2i,右孩子节点为2i+1
堆化是自上而下堆化,而array.length/2 + 1到array.length - 1是叶子节点,不需要堆化。
- 先堆化
- 取堆顶元素和数组最后一位交换,堆化第1位和倒数第二位,直至数组有序
public class HeapSort {
public static void main(String[] args) {
int[] nums = {10, 3, 2, 5, 6, 4, 3, 9, 8, 0,2,3,6,5};
headSort(nums);
System.out.println(Arrays.toString(nums));
}
public static void headSort(int[] array) {
buildHeap(array);
int k = array.length - 1;
while (k > 1) {
swap(array, k, 1);
k--;
heapify(array, k, 1);
}
}
public static void heapify(int[] array, int n, int i) {
while (true) {
int maxPos = i;
if (2 * i < n && array[i] < array[2 * i]) {
maxPos = 2 * i;
}
if (2 * i + 1 < n && array[maxPos] < array[2 * i + 1]) {
maxPos = 2 * i + 1;
}
if (maxPos == i) {
break;
}
swap(array, maxPos, i);
i = maxPos;
}
}
public static void buildHeap(int[] array) {
int len = array.length - 1;
for (int i = len / 2; i > 0; i--) {
heapify(array, len, i);
}
}
public static void swap(int[] array, int p, int q) {
int temp = array[p];
array[p] = array[q];
array[q] = temp;
}
}
数组首元素不空出来的写法
public class HeapSort2 {
public static void swap(int[] array, int p, int q) {
int temp = array[p];
array[p] = array[q];
array[q] = temp;
}
/**
* 自下而上堆化
*/
public static void heapInsert(int[] array, int i) {
while (array[(i - 1) / 2] < array[i]) {
swap(array, i, (i - 1) / 2);
i = (i - 1) / 2;
}
}
/**
*自上而下堆化
*/
public static void heapify(int[] array, int n, int i) {
int left = 2 * i + 1;
while (left < n) {
int changePos = array[left] > array[i] ? left : i;
changePos = ((left + 1) < n && array[left + 1] > array[changePos]) ? (left + 1) : changePos;
if (changePos == i) {
break;
}
swap(array, changePos, i);
i = changePos;
left = 2 * i + 1;
}
}
public static void heapSort(int[] array) {
int n = array.length;
for (int i = n / 2 - 1; i >= 0 ; i--) {
heapify(array, n, i);
}
int k = n;
while (k > 1) {
swap(array, --k, 0);
heapify(array, k, 0);
}
}
public static void main(String[] args) {
int[] nums = {10, 3, 2, 5, 6, 4, 3, 9, 8, 0,2,3,6,5,10};
heapSort(nums);
System.out.println(Arrays.toString(nums));
}
}