因此,我实施了一种快速选择算法,每次都选择一个好的支点。它的作用是将数组分成5个组,对每个组进行排序并找到中位数。然后它取每个组的中位数,将这些值组合起来,然后找到中位数的中位数。这就是我所拥有的:
private static int pickCleverPivot(int left, int right, int[] A){
int index = 0;
int n = right-left;
if (n <= 5) {
Arrays.sort(A);
index = n/2;
return index;
}
int numofMedians = (int) Math.ceil(n/5);
int[] medians = new int[numofMedians];
int[] groups = new int[5];
for(int i = 0; i < numofMedians; i++) {
if (i != numofMedians - 1){
for (int j = 0; j < 5; j++){
groups[j] = A[(i*5)+j];
}
medians[i] = findMedian(groups, 5);
} else {
int numOfRemainders = n % 5;
int[] remainder = new int[numOfRemainders];
for (int j = 0; j < numOfRemainders; j++){
remainder[j] = A[(i*5)+j];
}
medians[i] = findMedian(groups, 5);
}
}
return pickCleverPivot(left, left+(numofMedians), medians);
}
public static int findMedian(int[] A, int n){
Arrays.sort(A);
if (n % 2 == 0) {
return (A[n/2] + A[n/2 - 1]) / 2;
}
return A[n/2];
}
private static int partition(int left, int right, int[] array, int pIndex){
//move pivot to last index of the array
swap(array,pIndex,right);
int p=array[right];
int l=left;
int r=right-1;
while(l<=r){
while(l<=r && array[l]<=p){
l++;
}
while(l<=r && array[r]>=p){
r--;
}
if (l<r){
swap(array,l,r);
}
}
swap(array,l,right);
return l;
}
private static void swap(int[]array, int a, int b){
int tmp = array[a];
array[a] = array[b];
array[b] = tmp;
}
所以它应该像它应该的那样,但现在我想知道它是否有可能让它在线性O(n)时间内运行。我目前正在将此代码与仅选择随机数据透视表进行比较。在较小的阵列上,此代码运行得更快,但在较大的阵列上,选择随机数组会更快。因此,实际上可以在O(n)时间内进行运行,或者只是在理论上运行,如果它不可能以那么快的速度运行,那么这种方法可以尽可能快地运行。