#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;
}