堆排序思想:
首先将待排序的记录序列构造成一个堆,然后将堆顶元素移走,此时,选出了堆中所有记录的最大者即堆顶。并将剩余的记录再调整为堆,这样又找出了次大的元素,以此类推,直到堆中只有一个记录为止。
a.将无序序列构建成一个堆,根据升序降序需求选择大顶堆或小顶堆;
b.将堆顶元素与末尾元素交换,将最大元素"沉"到数组末端;
c.重新调整结构,使其满足堆定义,然后继续交换堆顶元素与当前末尾元素,反复执行调整+交换步骤,直到整个序列有序。
C++代码实现如下:
///----------------堆排序,堆下标从0~n-1
//筛选第k个结点,无序区的最后一个下标为m
void sift(int r[],int k,int m)
{
int i=k, j=2*k+1;
int tmp;
while(j<=m)
{
if(j<m&&r[j]<r[j+1]) j++;
if(r[i]>r[j]) break;
else
{
tmp=r[i];
r[i]=r[j];
r[j]=tmp;
i=j;
j=2*i+1;
}
}
}
//r为初始待排序序列,n为序列中元素的个数
void HeapSort(int r[],int n)
{
for(int i=(n-1)/2;i>=0;i--)
sift(r,i,n-1);
int tmp;
// 1
for(int i=0;i<n-1;i++)
{
tmp=r[0];
r[0]=r[n-1-i];
r[n-1-i]=tmp;
sift(r,0,n-2-i);
}
// 2 : 1或2取一
for(int i=n-1;i>0;i--)
{
tmp=r[0];
r[0]=r[i];
r[i]=tmp;
sift(r, 0, i-1);
}
}
int main()
{
int r[]={36,30,18,40,32,45,22,50};
HeapSort(r,8);
for(int i=0;i<8;i++)
cout<<r[i]<<" "; //18 22 30 32 36 40 45 50
return 0;
}