由于每次重新恢复堆的时间复杂度为O(logN),共N - 1次重新恢复堆操作,再加上前面建立堆时N / 2次向下调整,每次调整时间复杂度也为O(logN)。二次操作时间相加还是O(N * logN)。故堆排序的时间复杂度为O(N * logN)。
//堆排序:利用 最大堆 max_heap
//从数组的0位置开始
int LeftChild(int i){
return (2 * i + 1);
}
//对位置i上的元素进行下滤操作 percolate down
template<typename T>
void PercDown(T A[], int i, int N){
int child;
T tmp;
for (tmp = A[i]; LeftChild(i) < N; i = child){
child = LeftChild(i);
if (child != N - 1 && A[child + 1]>A[child]){
child++;
}
if (tmp < A[child]){
A[i] = A[child];
}
else{
break;
}
}
A[i] = tmp; //避免多次的交换操作
}
template<typename T>
void HeapSort(T A[], int N){
int i;
T tmp;
for (i = N / 2; i >= 0; i--){
PercDown(A, i, N); //build heap
}
for (i = N - 1; i > 0; i--){ //用来控制堆的大小
//swap(&A[0],&A[i]; //deletemax //每次删除最大值放到最后,完成后元素从小到大排列
tmp = A[0];
A[0] = A[i];
A[i] = tmp;
PercDown(A, 0, i);
}
}