在Java中以O(n)运行的快速选择?

时间:2016-09-30 23:59:00

标签: java arrays algorithm

因此,我实施了一种快速选择算法,每次都选择一个好的支点。它的作用是将数组分成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)时间内进行运行,或者只是在理论上运行,如果它不可能以那么快的速度运行,那么这种方法可以尽可能快地运行。

0 个答案:

没有答案