点击查看代码
#include<cstdio>
#include<stdlib.h> //使用srand()和rand()
#include<time.h> //使用time()
#include<cmath> //使用round()
#include<algorithm> //使用swap()
using namespace std;
#pragma warning(disable:4996)
//对区间[left,right]进行划分
int randPartition(int A[], int left, int right) {
//生成[left,right]范围内的随机数p
int p = (round(1.0 * rand() / RAND_MAX * (right - left) + left));
swap(A[p], A[left]); //将随机数A[p]作为分界点A[left]
int temp = A[left];
while (left < right) {
while (left < right && A[right] > temp) right--;
A[left] = A[right];
while (left < right && A[left] <= temp) left++;
A[right] = A[left];
}
A[left] = temp;
return left;
}
//随机选择算法,从A[left,right]中返回第K大的数
int randSelect(int A[], int left, int right, int K) {
if (left == right) return A[left]; //到达边界返回A[left]
int p = randPartition(A, left, right); //划分后主元的位置p
int M = p - left + 1; //A[p]是A[left,right]中的第M大个数
if (K == M) return A[p]; //找到第K大的数,则返回A[p]
else if (K < M) { //K<M,第K大数在主元左侧[left,p-1]
return randSelect(A, left, p - 1, K);
}
else { //K>=M,第K-M大数在主元右侧[left,p-1]
return randSelect(A, p + 1, right, K - M);
}
}
int main() {
srand((unsigned)time(NULL)); //生成随机数的种子
int a[] = { 5, 12, 7, 2, 9, 3 };
int K = 3;
printf("%d\n", randSelect(a, 0, 5, K)); //输出a[]中第3大的数,即元素5
return 0;
}