**堆排序是一种时间复杂度也为nlogn的一种排序,和快排的时间复杂度一样,但他在面对一些问题时能够用他的特殊性,更好的解决问题。
简单堆排的代码如下:
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#define MAX 100
using namespace std;
int h[MAX],n;
void swap(int *x,int *y)
{
int t = *x;
*x = *y;
*y = t;
return;
}
void siftdown(int i)
{
int t,flag = 0;
while(i*2 <= n && flag == 0)
{
t = i*2;//标记他的左二子
if(t+1<=n && h[t] > h[t+1])//如果他的右儿子存在,且比他的左儿子小
t = t+1;//那么更新为标记他的右儿子
/*这里是为了找出两个儿子中更小的那个*/
if(h[t] < h[i])//如果最小的那个儿子比他的父亲更小,则交换他们
swap(&h[t],&h[i]);
else
flag = 1;
i = t;//从这个节点继续向下
}
return;
}
void Creat()
{
int i;
for(i=n/2;i>=1;i--)//从n/2这个节点开始进行向下的操作
siftdown(i);
/*这一步可以理解为n/2相当于最后一个非叶的节点,或则是第一个叶节点,
从叶节点的上面开始进行向下的操作,最后扫描到第一个节点是就是一个完整的堆了。*/
return;
}
int deletemax()
{
/*利用最小堆的原理,把堆顶输出,然后把最后一个节点放在堆顶的位置,再更新堆。*/
int t;
t = h[1];
h[1] = h[n];
n--;
siftdown(1);
return t;
}
int main(void)
{
int i;
srand(time(NULL));
scanf("%d",&n);
for(i=1;i<=n;i++)
h[i] = rand() % 10000;
Creat();
int num = n;
for(i=1;i<=num;i++)
cout << deletemax() << endl;
return 0;
}