求第k大的数
给定一个长度为n(1≤n≤1,000,000)的无序正整数序列,以及另一个数k(1≤k≤1,000,000)(关于第k大的数:例如序列{1,2,3,4,5,6}中第3大的数是4。)
输入
第一行两个正整数m,n。
第二行为n个正整数。
输出
第k大的数。
样例输入 Copy
6 3
1 2 3 4 5 6
样例输出 Copy
4
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<cmath>
using namespace std;
int N[1000000];
int n;
double round(double r)
{
return (r>0.0)?floor(r + 0.5) : ceil(r - 0.5);
}
int quicksort(int l,int r)
{
int p=(round(1.0*rand()/RAND_MAX*(r-l)+l));
swap(N[p],N[l]);
int t=N[l];
while(l<r)
{
while(l<r&&N[r]>t) r--;
N[l]=N[r];
while(l<r&&N[l]<t)l++;
N[r]=N[l];
}
N[l]=t;
return l;
}
int select(int l,int r,int k)
{
if(l==r) return N[l];
int p=quicksort(l,r);
int m=r-p+1;
if(k==m) return N[p];
if(k>m) return select(l,p-1,k-m);
else return select(p+1,r,k);
}
int main()
{
int k;
while(scanf("%d%d",&n,&k)==2)
{
int i;
for(i=0;i<n;i++)
scanf("%d",&N[i]);
int p=select(0,n-1,k);
printf("%d\n",p);
}
return 0;
}
但是如果照算法笔记的意思是这样的
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<ctime>
#include<cmath>
using namespace std;
int N[1000000];
int n;
double round(double r)
{
return (r>0.0)?floor(r + 0.5) : ceil(r - 0.5);
}
int quicksort(int l,int r)
{
int p=(round(1.0*rand()/RAND_MAX*(r-l)+l));
swap(N[p],N[l]);
int t=N[l];
while(l<r)
{
while(l<r&&N[r]>t) r--;
N[l]=N[r];
while(l<r&&N[l]<t)l++;
N[r]=N[l];
}
N[l]=t;
return l;
}
int select(int l,int r,int k)
{
if(l==r) return N[l];
int p=quicksort(l,r);
int m=p-l+1;
if(k==m) return N[p];
if(k<m) return select(l,p-1,k);
else return select(p+1,r,k-m);
}
int main()
{
int k;
while(scanf("%d%d",&n,&k)==2)
{
int i;
for(i=0;i<n;i++)
scanf("%d",&N[i]);
int p=select(0,n-1,k);
printf("%d\n",p);
}
return 0;
}
但是这个答案是错误的!错误就出在select函数上面,可能是作者笔误,这个select函数求得的答案是计算第k小的数字而不是第k大的数字!纠正就在第一个代码里那个select函数,这里快排得到的答案就是增序的。
而且特坑的就是vs2010的cmath里没有round函数,这个要自己添加,抄自https://blog.csdn.net/u014485485/article/details/78939537?utm_source=blogxgwz7
……不会侵权吧?