堆排序是利用堆来进行排序。
堆的定义:n个元素的序列(a1,a2...an)当且仅当满足下面关系时,称为堆。
(a(i)<=a(2*i) && a(i)<=a(2*i+1))或者(a(i)>=a(2*i) && a(i)>=a(2*i+1))其中,2*i+1<=n。
堆的模型:可以借助完全二叉树来理解。每一节点的值均不大于或不小于其左右孩子节点的值。
代码如下:
#include<iostream>
using namespace std;
void shift(int a[],int k,int m) //调整堆,以k为根,m个数据
{
int i,j,tem;
bool finished;
tem=a[k];
finished=false;
i=k;
j=2*i;
while(j<=m && finished==false)
{
if(j<m && a[j]<a[j+1]) //左右孩子的大值用j指示
j++;
if(tem>=a[j])
finished=true;
else
{
a[i]=a[j];
i=j;
j*=2;
}
}
a[i]=tem;
}
void heap_sort(int a[],int n)
{
int i,tem;
for(i=n/2;i>=1;i--) //初始建堆
shift(a,i,n);
for(i=n;i>=2;i--)
{
tem=a[1]; //输出大数到数组尾部
a[1]=a[i];
a[i]=tem;
shift(a,1,i-1); //调整堆
}
}
int main()
{
int i,n,a[101];
while(cin>>n,n)
{
for(i=1;i<=n;i++) //注意:存放有用数据下标从1开始,建堆需要
cin>>a[i];
heap_sort(a,n);
for(i=1;i<=n;i++)
cout<<a[i]<<" ";
cout<<endl<<endl;
}
return 0;
}
Attention:
①时间复杂度为O(nlog2n),空间复杂度为O(n)。
②属于原地排序。