堆,其实是一颗完全二叉树(树的每一层都是满的,最后一层可能除外)。 二叉堆有两种,最小堆和最大堆,我们在对排序中主要用的是最大堆。
即key[i]>=key[i*2]&&key[i]>=key[i*2+1],简单的说就是父亲节点要比他的子节点要大。
排序过程:
(1)构造初始堆
(2)每次交换数组最后一个和第一个数,并调整堆
详见 http://www.cnblogs.com/dolphin0520/archive/2011/10/06/2199741.html
#include<bits/stdc++.h>
using namespace std;
void heapadjust(int h[],int i,int len)
{
int lson=i*2;
int rson=i*2+1;
int max=i;
if(i<=len/2)//i,lson,rson中寻找一个最大的节点来与i交换
{
if(lson<=len&&h[lson]>h[max])
{
max=lson;
}
if(rson<=len&&h[rson]>h[max])
{
max=rson;
}
if(max!=i)
{
swap(h[max],h[i]);
heapadjust(h,max,len);//调整完当前节点后,还需要对交换的叶子节点的位置进行调整
}
}
}
void buildheap(int h[],int len)
{
for(int i=len/2; i>=1; i--)//len/2是可能最大的一个非叶子节点
{
heapadjust(h,i,len);
}
}
void heapsort(int h[],int len)
{
buildheap(h,len);//构造初始堆
for(int i=len; i>=1; i--)
{
swap(h[1],h[i]);
heapadjust(h,1,i-1);//每交换一个元素,对堆的调整
}
}
int main()
{
int h[110],len;
scanf("%d",&len);
for(int i=1; i<=len; i++)
scanf("%d",&h[i]);
heapsort(h,len);
for(int i=1; i<=len; i++)
printf("%d ",h[i]);
puts("");
return 0;
}