#include <iostream>
using namespace std;
int get_kth(int arr[], int n, int k) {
int left = 0;
int right = n - 1;
while (left < right) {
while (arr[right] > arr[0] && left < right) {
right--;
}
while (arr[left] <= arr[0] && left < right) {
left++;
}
/**
* 两个小while结束后会有left < right 仍然成立
* 所以还会继续进行大的循环
* 然而,left已经达到我们想要的目的了
* 所以while(···) right--;一定要写在前替left"挡枪"
* 在又一次经历了递减后@right == left@ 了
* 所以left不会在进入while(···) left++;
* 第二次交换相当于swap(arr[left], arr[left])
* 这样一来left的值就被确保下来了
*/
/*//另一种写法
while (arr[left] <= arr[0] && left + 1 < right) {
left++;
}
while (arr[right] > arr[0] && left < right) {
right--;
}
//这个的推断理由跟上面的差不多
*/
cout << "前: left = " << left << " right = " << right << " | ";
for (int i = 0; i < n; ++i) {
cout << arr[i] << " ";
}
cout << endl;
swap(arr[left], arr[right]);
cout << "后: left = " << left << " right = " << right << " | ";
for (int i = 0; i < n; ++i) {
cout << arr[i] << " ";
}
cout << endl;
}
swap(arr[0], arr[left]);
for (int i = 0; i < n; ++i) {
cout << arr[i] << " ";
}
cout << endl;
//此时有left个小于a[0]的且全都排在a[0]前面
//有n - right 个大于a[0]的,切全都排在最后面(a[0]后面)
/**
* 下面的递归与right没有任何关系,
* 所以只需要保证left"安全"即可
*/
int _k = left + 1;//检索到小于目标(这里是a[0])的数量
if (_k == k) {
return arr[left];//之前的a[0]
} else if(_k < k) {
return get_kth(arr + _k, n - _k, k - _k);
}else if (_k > k){
return get_kth(arr, left, k);
}
}
int main() {
int a[] = {2, 1, 4, 6, 3, 5, 0};
int b[] = {1, 2, 3, 4, 5, 6, 7};
int c[] = {4, 1, 3, 7, 2, 5, 6};
int d[] = {9, 1, 2, 10, 13, 5, 11};
cout << get_kth(d, 7, 6) << endl;
}