堆排序
堆排序是指利用堆这种数据结构设计的一种排序算法,堆分为大顶堆和小顶堆,他是一个近似完全二叉树的结构。
大顶堆
每个节点的值都大于或者等于它的左右节点的值。
小顶堆
每个节点的值都小于或者等于它的左右节点的值。
性质
大顶堆:arr[i] >=arr[i * 2 + 1],arr[i] >= arr[i * 2 + 2]
小顶堆:arr[i] <= arr[i * 2 + 1],arr[i] <= arr[i * 2 + 2]
堆排序的步骤:
- 建堆
- 将堆首和堆尾交换
- 将堆的长度-1,调整堆的顺序,将最大值或者最小值放入堆首
- 重复第二步,直至堆的长度为1
下面是堆排序的实现
public class HeapSort {
public static void heapSort(int[] arr){
if(arr == null || arr.length < 2){
return;
}
for (int i = 1;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);
}
}
private static void heapify(int[] arr, int index, int heapSize) {
int left = index * 2 + 1;
while(left < heapSize){
int target = left + 1 < heapSize && arr[left] < arr[left +1] ? left + 1 : left;
target = arr[target] < arr[index] ? index : target;
if(target == index)
break;
swap(arr,target,index);
index = target;
left = index * 2 + 1;
}
}
private static void heapInsert(int[] arr, int index) {
while(arr[index] > arr[(index - 1) / 2]){
swap(arr,index,(index - 1) / 2);
index = (index - 1) / 2;
}
}
private static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
大顶堆,小顶堆的这种思想是非常好用的,有一些算法题目都是应用的这种思想,以后的博客我也会写一些这样的题目。