数组的联合可以在线性时间内完成。我跳过了那部分。
您可以使用quick sort 中使用的partition() 算法。在快速排序中,该函数必须递归两个分支。然而,这里我们只是有条件地调用递归调用,因此只有 1 分支递归。
主要概念:partition() 将选择的PIVOT 元素放置在其适当的排序位置。因此,我们可以使用这个属性来选择我们感兴趣的数组的那一半,然后在那一半上递归。这将阻止我们对整个数组进行排序。
我根据上述概念编写了以下代码。假设 rank = 0 意味着数组中的最小元素。
void swap (int *a, int *b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
int partition (int a[], int start, int end)
{
/* choose a fixed pivot for now */
int pivot = a[end];
int i = start, j;
for (j = start; j <= end-1; j++) {
if (a[j] < pivot) {
swap (&a[i], &a[j]);
i++;
}
}
/* Now swap the ith element with the pivot */
swap (&a[i], &a[end]);
return i;
}
int find_k_rank (int a[], int start, int end, int k)
{
int x = partition (a, start, end);
if (x == k) {
return a[x];
} else if (k < x) {
return find_k_rank (a, start, x-1, k);
} else {
return find_k_rank (a, x+1, end, k);
}
}
int main()
{
int a[] = {10,2,7,4,8,3,1,5,9,6};
int N = 10;
int rank = 3;
printf ("%d\n", find_k_rank (a, 0, N-1, rank));
}