(找第k大的数) 给定一个长度为1,000,000的无序正整数序列,以及另一个数n(1<=n<=1000000),接下来以类似快速排序的方法找到序列中第n大的数(关于第n大的数:例如序列{1,2,3,4,5,6}中第3大的数是4)。
#include <iostream>
using namespace std;
int a[1000001],n,ans = -1;
void swap(int &a,int &b)
{
int c;
c = a; a = b; b = c;
}
int FindKth(int left, int right, int n)
{
int tmp,value,i,j;
if (left == right) return left;
tmp = rand()% (right - left) + left;
swap(a[tmp],a[left]);
value = ①
i = left;
j = right;
while (i < j)
{
while (i < j && ② ) j --;
if (i < j) {a[i] = a[j]; i ++;} else break;
while (i < j && ③ ) i ++;
if (i < j) {a[j] = a[i]; j --;} else break;
}
④
if (i < n) return FindKth( ⑤ );
if (i > n) return ⑥
return i;
}
int main()
{
int i;
int m = 1000000;
for (i = 1;i <= m;i ++)
cin >> a[i];
cin >> n;
ans = FindKth(1,m,n);
cout << a[ans];
return 0;
}
答案:
① a[left];
② a[j] < value (或a[j] <= value)
③ a[i] > value (或a[i] >= value)
④ a[i] = value;
⑤ i + 1,right,n
⑥ FindKth(left, i – 1, n);
该题为noip2008提高组初赛题目
利用的是快排的思想,由大到小排序。
笔者喜欢从小到大的排序,所以将程序修改

1 #include <iostream> 2 #include<stdlib.h> 3 using namespace std; 4 5 int a[1000001],n,ans = -1; 6 void swap(int &a,int &b) 7 { 8 int c; 9 c = a; a = b; b = c; 10 } 11 12 int FindKth(int left, int right, int n) 13 { 14 int tmp,value,i,j; 15 if (left == right) return left; 16 tmp = rand()% (right - left) + left; 17 swap(a[tmp],a[left]); 18 value = a[left]; 19 i = left; 20 j = right; 21 while (i < j) 22 { 23 while (i < j && a[j] > value ) j --;//如果 a[j] > value则j左移 24 if (i < j) {a[i] = a[j]; i ++;} else break; 25 while (i < j && a[i] < value ) i ++; 26 if (i < j) {a[j] = a[i]; j --;} else break; 27 } 28 a[i] = value; 29 for (int i=1;i<=5;i++)cout<<a[i]<<" "; 30 cout<<endl; 31 if (i < n) return FindKth( i + 1,right,n ); 32 if (i > n) return FindKth(left, i - 1, n); 33 return i;//找到第n大的数则返回 34 } 35 36 int main() 37 { 38 int i; 39 int m = 5; 40 for (i = 1;i <= m;i ++) 41 cin >> a[i]; 42 cin >> n; 43 ans = FindKth(1,m,m-n+1);//找第n大的数 (因为从大到小排序所以为m-n+1) 44 cout << a[ans]; 45 return 0; 46 }