大根堆定义为,每一个父亲节点都大于等于左右两个孩子节点(小根堆同理)。并且,大根堆一定是一棵完全二叉树。思想为从最后一个家庭开始(最后一个有孩子的父亲节点),将这个家庭调整为大根堆,然后父亲节点前移,将下一个家庭调整为大根堆……以此类推,最后,根节点就是最大的元素,然后将根节点与最后一个叶子节点交换,砍掉最后一个叶子节点(意思就是下一轮的排序它不参与)。
#include <stdio.h>
void HeapSort(int a[],int n)
{
int rear,t,pa,tag=0;//tag:标志变量 用处:检查大根堆是否完成
rear=n;
while(rear>1)
{
while(1)//与检查tag变量是否有变化一起合作,调整成大根堆
{
pa=rear/2;//最后一个父亲节点,rear奇偶情况都适用
tag=0;
while(pa>0)
{
if(a[pa]<a[pa*2])//左子女不用检查 直接比较
{
t=a[pa];
a[pa]=a[pa*2];
a[pa*2]=t;
tag=1;
}
if(2*pa+1<=rear&&a[pa]<a[pa*2+1])//右子女检查是否存在 再比较
{
t=a[pa];
a[pa]=a[pa*2+1];
a[pa*2+1]=t;
tag=1;
}
pa--;
}
if(!tag)//是否调整成大根堆的判断
break;
}
t=a[1];//交换"头"与"尾" "砍掉"!
a[1]=a[rear];
a[rear]=t;
rear--;
}
}
int main(void)
{
int a[11]={0,1,3,6,8,4,2,5,9,7,10};
int i;
HeapSort(a,10);
for(i=10;i>0;i--)
printf("%d\t",a[i]);
return 0;
}
时间复杂度:o(nlogn) 不稳定