package sort;
import java.util.Arrays;
public class HeapSort {
public static void main(String[] args) {
int[] a = {3,6,2,9,5,8,7,1,4};
heapSort(a);
System.out.println(Arrays.toString(a));
}
/*堆排序,可认为是一种优化的选择排序,可分为两步
第一步建堆,第二步执行n-1次deleteMax
注意堆排序使用的堆和标准二叉堆略有不同,一是使用最大堆而不是最小堆;二是数据从数组下标0开始(二叉堆从1开始)*/
public static void heapSort(int[] a){
//buildHeap
//a.length/2 - 1 是怎么得到的?在二叉堆中位置i的父节点是floor(i/2),因此在堆排序中是floor((i+1)/2)-1,
//把i=a.length-1带入即得。
for (int i = a.length/2 - 1; i>=0; i--)
percDown(a, i, a.length);
//deleteMax
for (int i = a.length -1; i>0; i--){
//注意下滤时堆在不断变小,即已经排好序的数虽然还在数组里但不属于堆的一部分
swap(a, 0, i);
percDown(a, 0, i);
}
}
//核心方法——下滤
//从位置i开始下滤,即“空穴”的位置。n是堆大小
private static void percDown(int[] a, int i, int n) {
//使用和插入排序相同的小技巧。不显式使用交换
int tmp = a[i];
while(leftChild(i) < n){
int child = leftChild(i);
//确定两个儿子中较大的那个
if (child != n-1 && a[child] < a[child+1])
child++;
if (tmp < a[child])
a[i] = a[child];
else
break;
i = child;
}
a[i] = tmp;
}
private static int leftChild(int i) {
return 2 * i + 1;
}
private static void swap(int[] a, int i, int j) {
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
}
排序算法之堆排序
最新推荐文章于 2024-07-31 16:52:17 发布