#include<iostream>
using namespace std;
typedef int ElemType;
/*
堆排序算法的性能分析如下:
空间效率:仅使用了常数个辅助单元,所以空间复杂度为O(1)。
时间效率:建堆时间为O(n),之后有n-1次向下调整操作,每次调
整的时间复杂度为Oh),故在最好、最坏和平均e况下,堆排序的
时间复杂度为O(nlog2n)。
稳定性:进行筛选时,有可能把后面相同关键字的元素调整到
前面,所以堆排序算法是一种不稳定的排序方法。
*/
/*
调整的时间与树高有关,为O(h)。在建含n个元素的堆时,关
键字的比较总次数超过4n时间复杂度为O(n),这说明可以在
线性时间内将一个无序数组建成一个堆。
*/
void HeadAdjust(ElemType A[],int k,int len){
//函数 HeadAdjust将元素k,为根的子树进行调整
int i;
A[0] = A[k]; //A[0]暂存子树的根节点
for(i = 2*k;i <= len;i*=2){ //沿key较大的子结点向下筛选
if(i < len && A[i] <A[i+1]){
i++; //取key较大的子结点的下标
}
if(A[0] >= A[i]){ //筛选结果
break;
}
else{
A[k] = A[i]; //将A[i]调整到双亲结点上
k = i; //修改k值,以便继续向下筛选
}
}
A[k] = A[0]; //被筛选结点的值放入最终位置
}
void BuildMaxHeap(ElemType A[],int len){
for( int i = len/2;i > 0;i--){ //从i= [n/2]~1,反复调整堆
HeadAdjust(A,i,len);
}
}
void HeapSort(ElemType A[],int len){
int i,temp;
BuildMaxHeap(A,len); //c初始建堆
for(i = len;i > 1;i--){ //n-1趟的交换和建立堆过程
temp = A[i]; //输出堆顶元素(和堆底元素交换)
A[i] = A[1];
A[1] = temp;
HeadAdjust(A,1,i-1); //调整,把剩余的i-1个元素整理成堆
}
}
int main(){
ElemType A[] ={ 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
int len = (int) sizeof(A) / sizeof(*A);
HeapSort(A,len);
for(int i =0;i<len;i++){
cout<<A[i]<<" ";
}
}