排序算法_堆排序
首先要理解什么是堆,简单的说堆就是个数组,假设有一个数组:[1,2,3,4,5],
那么抽象成一个堆就是这个样子滴:
下标为0位置的作为根,这样每一个子树根部都是最小值的情况,称这个树为小根堆,相反,如果每一个子树的根节点都是最大值,就是大根堆,
假设现在根位置的值变为9,即数组为[9,1,2,3,4,5]:那么从小到大排的顺序应该是[1,2,3,4,5,9].写一个循环,假设循环从0开始,那么需要比较下标为2 i+1和2i+2位置的值谁比较小,比较小的值和下标为i的值进行交换,重复这个过程,最终最小值排列到下标为0的位置,下面是具体的实现:
public static void heapSort(int[] arr) {
if (null == arr || arr.length < 2) {
return;
}
//建立大根堆
for (int i = 0; i < arr.length; i++) {
heapInsert(arr, i);
}
int heapSize = arr.length;
swap(arr,0,--heapSize);
//堆调整排序
while (heapSize > 0) {
//再次形成大根堆
heapify(arr,0,heapSize);
swap(arr,0,--heapSize);
}
}
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 heapify(int[] arr, int index, int heapSize) {
int left = index * 2 + 1;
while (left < heapSize) {
int largest = left + 1 < heapSize && arr[left + 1] > arr[left]
?left + 1:left;
largest = arr[largest] > arr[index]?largest:index;
if (largest == index) {
break;
}
swap(arr,largest,index);
index = largest;
left = index * 2 +1;
}
}