思路:我们在这里用到一个快排的思想,快排一次得到位置pos,在这个pos之前的数据全比和比较的数小(或者大),它后面的数全比和比的数大(或者小),如下图,快排第一次用6来和其他数比较,排序一次之后,在6之前的数字一定会比6小,在6之后的数字一定会比6大。
如果你要找第3小则需要在6前面找,就要执行quicksort(arr, left, index, k);反之,找第7小的话,就需要在6后面找了,执行quicksort(arr, index + 1, right, k - pos);
下一次查找的时候是7和8,因为第一次排序的时候已经知道了前面有6个小的,所以在7和8中找的话就需要找第一小,加上前面的6个就是第七小,这个时候pos = 1;执行quicksort(arr, left, index, k);这个时候left == right ,k == 1,返回它就可以了
退出条件是left == right && k == 1的时候,刚好找到这个数,返回它。
#include<iostream>
using namespace std;
int postion(int *arr, int left, int right)
{
int i = left;
int j = right;
int tmp = arr[left];
while (i < j)
{
while (i < j && tmp < arr[j])
{
j--;
}
if (i < j)
{
arr[i] = arr[j];
}
while (i < j && tmp > arr[i])
{
i++;
}
if (i < j)
{
arr[j] = arr[i];
}
}
arr[i] = tmp;
return i;
}
int quicksort(int *arr, int left, int right, int k)
{
if (left == right && k == 1)
{
return arr[left];
}
int index = postion(arr, left, right);
cout << index << endl;
int pos = index - left + 1;
if (k > pos)
{
quicksort(arr, index + 1, right, k - pos);
}
else
{
quicksort(arr, left, index, k);
}
}
int main()
{
int arr[] = { 6, 3, 8, 2, 5, 1, 7,4 };
int n = sizeof(arr) / sizeof(int);
int k;
cin >> k;
int x = quicksort(arr, 0, n - 1, k);
cout << k << " => " << x << endl;
/*for (int k = 1; k <= n; ++k)
{
int x = selectK_min(arr, n - 1, k);
cout << k << " => " << x << endl;
}*/
return 0;
}