如果查找第i小的元素,当然我们可以先排序,再得到第i个元素,是可以的,但有时候排序的话,时间复杂度往往很高,O(nlgn)或者O(n*n),下面看一下,不通过排序来查找第i小的元素。见算法导论第二版(186页)
先介绍两个函数,此函数的作用是将数组A【p, r】分成两部分,一部分大于A[r],一部分小于A[r],A[r]是分隔点。函数的返回值是A[r]元素在数组中的新位置。
PARTITION(A, p, r)
{
x<--A[r]
i<--p-1
for j<--p to r-1
{
if (A[j] <=x)
{
i++;
// 现在 i 是大于A[r]的第一个元素
exchange A[i]<-->A[j]
}
}
exchange A[j+1] <--> A[r]
}
PARTITION 中的A[r],现在可以换成 A[p...r]的任何一个元素
RANDOMIZED_PARTITION(A, p, r)
{
i<--RANDOM(p, r) // 生成 p到r 之间的随机数
exchange A[r] <--> A[i]
return PARTITION(A, p, r)
}
开始递归查找
RANDOMIZED_SORT(A, p, r, i)
{
if p==r
return A[p]
q <-- RANDOMIZED_PARTITION(A, p, r) // q 是 分割点所在的位置
k <-- q-p+1 // 小于等于q的元素个数
if i==k // 找到
return A[q];
else if i<k
return RANDOMIZED_SORT(A, p, q-1, i)
else return RANDOMIZED_SORT(A, q+1, r, i-k)
}
附件中试C语言的示例代码
1851





