堆排序
/**
* 堆排序
* 什么是堆排序?首先知道数组转化完全二叉树的左子树为a[2*i+1],子节点的父节点是(i-1)/2,
* 将数组建成大顶堆,将堆顶元素与最后一个元素换掉,最后一个元素到了堆顶,调整堆为大顶堆,依次过程,直到堆大小为0
*/
public class HeapSort {
public static void heapSort(int[] a) {
if (a == null || a.length < 2) {
return;
}
for (int i = 0; i < a.length; i++) {
heapInsert(a, i); //0~i建大顶堆
int heapSize = a.length;
swap(a, 0, --heapSize);
while (heapSize > 0) {
heapfy(a, 0, --heapSize);
swap(a, 0, --heapSize);
}
}
}
//调整成最大堆
public static void heapfy(int[] a, int index, int size) {
int left = index * 2 + 1;
while (left < size) {
//取左右子树中的最大值,left为右子树,并保证右子树不越界
int largest = left + 1 < size && a[left] > a[left + 1] ? left : left + 1;
//子树最大值和本身相比取最大值
largest = a[index] > a[largest] ? index : largest;
//如果本身已经是最大值了停止交换
if (largest == index) {
break;
}
swap(a, largest, index);
index = largest;
left = index * 2 + 1;
}
}
//建大顶堆
public static void heapInsert(int[] arr, int index) {
while (arr[index] > arr[(index - 1) / 2]) {
swap(arr, index, (index - 1) / 2);
index = (index - 1) / 2;
}
}
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}