利用快速排序思想,每次把一个数找到他应该在的位置,然后如果当前位置满足条件,直接返回,如果这个数(包括这个数)
前面的数的个数小于k,那么第k大在后面的区间,否则在前面的区间,同时还要修改参数。
复杂度O(n)
#include <stdio.h>
int quick_select(int a[], int l, int r, int k)
{
int p = rand() % (r - l + 1) + l;
int x = a[p];
{
int t = a[p];
a[p] = a[r];
a[r] = t;
}
int i = l, j = r;
while (i < j)
{
while (i < j && a[i] < x)
i++;
if (i < j)
{
a[j] = a[i];
j--;
}
while (i < j && a[j] > x)
j--;
if (i < j)
{
a[i] = a[j];
i++;
}
}
a[i] = x;
p = i;
if (i - l + 1 == k)
return a[i];
if (i - l + 1 < k)
return quick_select(a, i + 1, r, k - (i - l + 1)); //???
else
return quick_select(a, l, i - 1, k);
}
int main()
{
int a[] = {1, 4, 2, 8, 5, 7, 23, 58, 16, 27, 55, 13, 26, 24, 12};
printf("%d\n", quick_select(a, 0, 14, 5));
return 0;
}