有这样一道题
heapsort
(heapsort.pas/c/cpp)
【问题描述】
堆排序,针对快排,有2组退化数据。
【输入】
第一行1个数n,表示数字的个数
第二行n个数。
【输出】
按升序输出的n个灵敏
【输入输出样例】
输入样例:
3
2 1 3
输入样例:
1 2 3
规模:n=100000,每个数值大小在longint范围内。
RT,针对快排有两组退化数据,那么快排就没法AC
/*
q_sort
http://oijzh.cnblogs.com
*/
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 100000+10
int n,a[MAXN];
void qs(int l,int r)
{
int i=l,j=r,x=a[(l+r)>>1];
do{
while(a[i]<x)i++;
while(a[j]>x)j--;
if(i<=j)
{
int t=a[i];a[i]=a[j];a[j]=t;
i++;j--;
}
}while(i<=j);
if(i<r)qs(i,r);
if(l<j)qs(l,j);
}
int main()
{
freopen("heapsort.in","r",stdin);
freopen("heapsort.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
qs(1,n);
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
return 0;
}
但是普通快排是每次取中,理想情况是n*log2n,但最坏可能会达到n2,所以这种快排是不稳定的,主要看RP
还有一种叫做随机化快排,快排是每次取中,而它则是每次在[l,r]区间中随机,这样就可以避免这种极端情况
/*
random_q_sort
http://oijzh.cnblogs.com
*/
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 100000+10
int n,a[MAXN];
void qs(int l,int r)
{
int ran=rand()%(r-l+1);//在此进行随机化
int i=l,j=r,x=a[ran+l];
do{
while(a[i]<x)i++;
while(a[j]>x)j--;
if(i<=j)
{
int t=a[i];a[i]=a[j];a[j]=t;
i++;j--;
}
}while(i<=j);
if(i<r)qs(i,r);
if(l<j)qs(l,j);
}
int main()
{
freopen("heapsort.in","r",stdin);
freopen("heapsort.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
qs(1,n);
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
return 0;
}
再来看下面这个报告,随机快排虽然可以避免极端情况,但是在随机数据(即不是刻意针对快排设计的数据)的时候,随机化快排和普通快排的效率是差不多的
既然是C++,那么就要发挥它STL的作用,看看下面的代码,是不是很简单,并且秒过所有测试数据!
/*
STL_sort
http://oijzh.cnblogs.com
*/
#include<cstdio>
#include<algorithm>
using namespace std;
#define MAXN 100000+10
int n,a[MAXN];
int main()
{
freopen("heapsort.in","r",stdin);
freopen("heapsort.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)
printf("%d ",a[i]);
return 0;
}
那么为什么STL会这么快呢
好了,剩下的就是题目要求的算法,堆排序
/*
heap_sort
http://oijzh.cnblogs.com
*/
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define MAXN 100000+10
int n;
vector<int> a;
bool cmp(int a,int b)
{ return a>b; }
int main()
{
freopen("heapsort.in","r",stdin);
freopen("heapsort.out","w",stdout);
scanf("%d",&n);
int x;
for(int i=1;i<=n;i++)
{
scanf("%d",&x);
a.push_back(x);
}
make_heap(a.begin(),a.end(),cmp);
for(int i=1;i<=n;i++)
{
printf("%d ",a.front());
pop_heap(a.begin(),a.end(),cmp);
a.pop_back();
}
return 0;
}