#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false)
using namespace std;
typedef long long ll;
const int maxn=1000;
//二分法在无序序列中找到第k小的数
int find_k(int l,int r,int a[],int k){
if(l==r)return a[l];
int mid=a[l];//将访问区间的第一个作为分界标准值
int pre=l,rear=r+1;
//将所有小于mid的放到mid左边,大于mid的放到mid右边,两遍都有可能存在等于mid的
while(pre<rear){
while(pre<r&&a[++pre]<mid);//从左边开始找不小于mid的数
while(a[--rear]>mid);//从右边找不大于mid的数
if(pre<rear)//如果没有到达分界处就交换
swap(a[pre],a[rear]);
}
a[l]=a[rear];
a[rear]=mid;//将标准值放到分解处(a[rear]保证了小于mid所以可以交换)
if(k==rear)return a[rear];//如果rear的值正好是k,根据搜索的原理,第k小的数肯定等于a[rear];
//根据k所在区间搜索左或右两个区间
if(k<rear){
return find_k(l,rear-1,a,k);
}
else{
return find_k(rear+1,r,a,k);
}
}
int main()
{
IOS;
int n,k;
int a[maxn];
cout<<"序列元素的个数:";
cin>>n;
cout<<"第k小数:k=";
while(cin>>k){
if(k<1||k>n){
cout<<"输入的k应该在区间[1:n]范围,请重新输入"<<endl;
cout<<"k=";
}
else break;
}
cout<<"输入"<<n<<"个元素值(空格间隔):";
for(int i=1;i<=n;i++){
cin>>a[i];
}
int ans=find_k(1,n,a,k);//求a[1:n]内第k小的数
cout<<"ans="<<ans<<endl;
getchar();
getchar();
return 0;
}