算法思想:将数组a[n]按照某一主元素进行划分,使数组左边的元素都小于主元素,数组右边的元素都大于主元素;
假设主元素左边的元素个数为k,此时,判断k是否等于i,如果相等则返回,否则如果k大于i,则在数组左半边搜索
第i大的元素,否则在数组右半边搜索第i-k大的元素。
java代码如下:
/**
* 查找数组中第i大的元素。
* @param a 数组
* @param p 数组下界
* @param r 数组上界
* @param i 第i大的元素,i>=1
* @return 数组中第i大的元素值
*/
public static int searchi(int[] a, int p, int r, int i) {
if (p == r) {
return a[p];
}
int k = partition(a, p, r);
int q = k - p + 1;
if (q == i)
return a[k];
else if (q > i)
return searchi(a, p, k - 1, i);
else
return searchi(a, k + 1, r, i - q);
}
/**
* 将数组划分使左边小于主元,右边大于主元,并返回主元索引
* @param a 数组
* @param p 下界
* @param r 上界
* @return 主元索引
*/
private static int partition(int[] a, int p, int r) {
int k = p - 1;
for (int i = p; i < r; i++) {
if (a[i] < a[r]) {
int t = a[k + 1];
a[k + 1] = a[i];
a[i] = t;
k++;
}
}
int t = a[k + 1];
a[k + 1] = a[r];
a[r] = t;
return k + 1;
}