堆排序是选择排序的优化,都是不稳定排序,在所以情况下的时间复杂度均为o(nlgn),只需一个额外空间,空间复杂度为o(1)。堆排序先要按照数字顺序建立完全二叉树,再建立二叉堆(即大堆或小堆,双亲节点大于或小于孩子节点),再依次将树根移动到后面,重新建立二叉堆,依次循环。
#include<iostream>
#include<stdlib.h>
using namespace std;
void dadui(int num[],int i,int len)//保证以i为顶点的子树中,num[i]是最大值
{
int logo;
int max=num[i];
if(i<=(len-1)/2)//迭代结束的条件为节点为叶子节点
{
//将该节点的值与左孩子比较
if(2*i+1<len&&num[2*i+1]>max)
{
max=num[2*i+1];
logo=2*i+1;
}
//将该节点的值与右孩子比较
if(2*i+2<len&&num[2*i+2]>max)
{
max=num[2*i+2];
logo=2*i+2;
}
//若该节点不是最大值,则与最大的孩子进行交换
if(max!=num[i])
{
num[logo]=num[i];
num[i]=max;
dadui(num,logo,len);//交换好之后,重新整理以进行交换的孩子为双亲的子树
}
}
}
void pailie(int num[],int len)
{
int temp;
for(int i=len-1;i>=0;i--)//因为是大堆顶,所以每次num[0]为最大值,将num[0]与num[len]进行交换
{
temp=num[0];
num[0]=num[i];
num[i]=temp;
len--;//为了保证最大值在后
dadui(num,0,len);
}
}
int main()
{
int len=5;
int num[5];
for(int i=0;i<5;i++)
cin>>num[i];
for(int i=(len-1)/2;i>=0;i--)
dadui(num,i,len);//建立大堆,由最大的非叶子节点开始向前推进
pailie(num,len);//排序
for(int i=0;i<5;i++)
cout<<num[i];
system("pause");
return 0;
}