原理如下:
代码如下:
#include <stdio.h>
void HeadAdjust(int a[],int k,int len){
int i;
a[0]=a[k]; //a[0]暂存子树的根节点
for(i=2*k;i<=len;i*=2){ //i是根节点的左孩子节点
if(i<len && a[i]<a[i+1]){ //i<len是为了判断是否存在右孩子节点,并且右孩子比左孩子大i++
i++;
}
if(a[0]>=a[i]){ //根节点本来就最大,筛选借宿
break;
}
else{
a[k]=a[i]; //将a[i]调整到双亲节点上
k=i; //修改k值,以便继续向下筛选
}
}
a[k]=a[0]; //被筛选的节点值放入最终位置
}
void BuildMaxHeap(int a[],int len){
for(int i=len/2;i>0;i--){ //从i=[n/2]-1反复调整堆
HeadAdjust(a,i,len);
}
}
void HeadSort(int a[],int len){
int i,temp;
BuildMaxHeap(a,len); //建立大根堆
for(i=len;i>1;i--){ //交换头部与尾部位置,使尾部最大
temp=a[i];
a[i]=a[1];
a[1]=temp;
HeadAdjust(a,1,i-1); //把剩余n-1个元素整理成堆,依次类推
}
}
int main()
{
int a[]={0,49,38,65,97,76,13,27,49,55,4};
HeadSort(a,10);
for(int i=1;i<10;i++){
printf("%3d",a[i]);
}
}