堆排序是构建最大堆后,将堆顶元素(最大数)与最后一个元素交换,然后将剩下的数重新构建最大堆,再将当前堆中的堆顶元素与最后一个元素交换,直至当前堆中无元素为止。
为了方便表示堆的左右孩子,我们使元素角标从1开始,假如s表示父亲结点,那么左孩子2s,右孩子2s+1
private static void heapSort(int[] a,int n) {
//第一次构建最大堆
for (int i = n/2; i > 0; i--) {
heapAdjust(a,i,n);
}
//i从最后一个元素开始
for (int i = n; i > 0; i--) {
//交换堆顶部元素1与最后一个元素i
swap(a, i, 1);
//剩下的元素继续构建最大堆
heapAdjust(a, 1, i-1);
}
}
private static void heapAdjust(int[] a, int s, int length) {
//s表示父亲结点,那么左孩子2s,右孩子2s+1
int temp = a[s];
for (int i = 2*s; i <= length; i*=2) {
//找到孩子的最大值
if (i<length && a[i] < a[i+1]) {
i++;
}
//父亲结点比孩子大,当前已满足最大堆
if(temp>= a[i] ){
break;
}
//否则父亲结点是孩子中最大的
a[s] = a[i];
s = i;
}
a[s] = temp;
}