找了一圈返回第k大数并返回下标的算法没找到,故在利用快排思想找数的算法基础上做了修改。本算法利用一个数组记录原下标的变化,最后输出该下标:
public static void main(String[] args)throws Exception {
test ts=new test();
double[] Sum=new double[]{1,0.5,2.8,0,2.2,3.3,5.2,1.8};
int[] index=new int[Sum.length]; // 下标记录数组
for (int i = 0; i < index.length; i++) { //下标数组赋初值
index[i]=i;
}
double[] b= Sum.clone(); //克隆数组
System.out.println(ts.choose_nth(b, index, 0, Sum.length - 1, 8)); //输出返回的下标
}
public int choose_nth(double nums[], int index[],int startIndex, int endIndex, int n)
{
double midOne = nums[startIndex];//把第一个值作为支点
int i = startIndex, j = endIndex,temp,midindex=index[startIndex];
if(i == j) //递归出口之一
return index[i];
if(i < j){
while(i < j){
while (i < j && nums[j] >= midOne) {
j--;
}
if (i < j) {
temp=i;
nums[i] = nums[j];
index[i]=index[j];
i++;
}
while (i < j && nums[i] < midOne) {
i++;
}
if (i < j) {
temp=j;
nums[j] = nums[i];
index[j]=index[i];
j--;
}
}
nums[i] = midOne;//支点归位
index[i]=midindex;
//此时a[i]这个数必定处于它真正的位置上,左边的都比他小,右边的都比他大;
int th = endIndex - i + 1;//计算下标为i的数第几大,都使用下标进行计算;
if(th == n){//正好找到
return index[i];
}
else{
if(th > n)//在支点右边找
return choose_nth(nums, index,i + 1, endIndex, n);
else//在支点左边找第(n-th)大,因为右边th个数都比支点大
return choose_nth(nums, index,startIndex, i - 1, n - th);
}
}
return 0;
}