这里直接使用大根堆
我们可以发现在二叉堆中,注意这里以下标1为数组的起始位置。
父节点k的子节点为2*k和2*k+1
根据这个规律,我们可以用数组来表示排序好的大根堆,利用上面说的父节点和子节点的规律进行排序。
我们定义一个sink函数,比较在一个父节点下哪一个子节点更大,将这个更大的节点与父节点比较,如果大于父节点将其与父节点交换。
直接上代码
#include <iostream>
#define MAXN 100
using namespace std;
int N;
int a[MAXN];
//比较大小
bool Less(int i,int j)
{
return (a[i]-a[j])<0?true:false;
}
void sink(int a[],int k,int N)
{
while(2*k<=N)
{
int j=2*k;
//取该父节点下子节点中较大的元素
if(j<N&&Less(j,j+1))
j++;
if(j<=N&&Less(k,j))
{
swap(a[k],a[j]);
k=j;
}
else break;
}
}
void sort()
{
int n=N;
//建立一个排序好的堆
for(int i=n/2;i>0;i--)
sink(a,i,n);
//建立一个排序好的数组
while(n>1)
{
//将堆首的元素转移到堆尾
swap(a[1],a[n]);
//将堆尾的元素从堆中剔除
n--;
//重新对堆进行排序
sink(a,1,n);
}
}
int main()
{
cin>>N;
for(int i=1;i<=N;i++)
scanf("%d",&a[i]);
sort();
for(int i=1;i<=N;i++)
printf("%d ",a[i]);
return 0;
}