#include <iostream>
using namespace std;
#define NUM 1001
int a[NUM];
//在a[left]~a[right]中寻找第k小的数
int select(int left, int right, int k)
{
if (left >= right) return a[left];//找到了
int i = left; //从左到右的指针
int j = right+1; //从右到左的指针
int pivot = a[left];//把最左边的元素当做分界数据
//把左边>= pivot的元素和右边<=pivot的元素交换
while (true)
{
//在左侧寻找>=pivot的元素
do {
i = i+1;
} while (a[i] < pivot);
//在右侧寻找<=pivot的元素
do {
j = j-1;
} while (a[j] > pivot);
if (i >= j) break;
swap(a[i], a[j]);
}
//快速排序算法中描述的nleft=j-left; 即分界数据的位置
if (j-left+1 == k) return pivot;
a[left] = a[j];
a[j] = pivot;
if (j-left+1 < k)
//对每一段进行递归调用
return select(j+1, right, k-j+left-1);//在右子集中查找
else
return select(left, j-1, k);//在左子集中查找
}
int main()
{
int n, k;
while (cin>>n>>k)
{
for (int i=0; i<n; i++)
cin>>a[i];
cout<<select(0, n-1, k)<<endl;
}
return 0;
}
算法分析:记一趟快速排序后,分解出左子集中元素个数为nleft(1)nleft=k-1,则分界数据就是答案(2)nleft>k-1,则选择问题的答案在左子集中寻找(3)nleft#include using namespace std;#define NUM 1001int a[NUM];//在a[left]~a[right]中寻找第k小的数 int select(int l