堆排序这个理解思想挺简单的。
以升序排序为例:就是一个完全二叉树,根结点始终小于子节点。
最开始是无序状态的堆,这时候我们需要解决两个问题:
(1)如何让无序状态的堆变成有序状态的堆
(2)如何输出堆顶元素后使得剩余元素成为新堆且满足以上要求
解决问题一:
我们从最后的一个非叶子节点开始,比较此节点和它的子节点,保证这个子树是有序的,如果无序我们就层层交换,以使得有序。
解决问题二:
我们每次输出堆顶元素,即根结点,然后将最后一个叶子节点元素放入根结点,这样可以尽可能的减少堆的移动,然后再将重新整理堆,使得堆有序。结束
代码:
#include <cstdio>
#include <iostream>
using namespace std;
int a[100005];
int n;
void heapadjust (int s,int m)
{
for(int j = s * 2; j <= m; j = j*2)
{
if( j < m && a[j] > a[j+1]) j++;
if(a[j] > a[s]) break;
swap(a[j],a[s]);
s = j;
}
}
void heapsort()
{
for(int i = n/2; i > 0; i--)
heapadjust(i,n);
for(int i = n; i > 1; i--)
{
cout<<a[1]<<" ";
a[1] = a[i];
heapadjust(1,i-1);
}
}
int main()
{
cin>>n;
for(int i = 1; i <= n; i++)
cin>>a[i];
heapsort();
cout<<a[1]<<endl;
return 0;
}