javaalgorithmselectionmedian-of-medians

Median of medians select algorithm


for the last few days I've been trying really hard to write this algorithm but without success. The code works and most of the time it gives me the right result but there are some cases where it fails. For example with this array {3, 8, 1, 9, 10, 7, 6, 2, 5, 4} and k = 6 it should give me 6 as result but it gives me 7. Can someone help me? I can't figure out what's the problem.

Here is the code:

class MOMSelect {

static int median(int a[], int i, int n) {
    if(i <= n)
        Arrays.sort(a, i, n);
    else
        Arrays.sort(a, n, i);
    return a[n/2];
}

static int medianOfMediansSelect(int a[], int left, int right, int k) {
    int n = right - left + 1;
    int i;
    int[] medians = new int[(n + 4) / 5];
    for (i = 0; i < n/5; i++) {
        medians[i] = median(a, left + i * 5, 5);
    }
    if (i*5 < n) {
        medians[i] = median(a,left + i * 5, n % 5);
        i++;
    }
    int medianOfMedians = (i == 1)? medians[i - 1]: median(medians, 0, medians.length);
    int pivotIndex = partition(a, left, right, medianOfMedians);
    if (pivotIndex == k - 1) {
        return a[pivotIndex];
    }
    else if (pivotIndex - left > k - 1) {
        return medianOfMediansSelect(a, left, pivotIndex - 1, k);
    }
    else {
        return medianOfMediansSelect(a, pivotIndex + 1, right, k);
    }
}

static void swap(int[] a, int i, int j) {
    int temp = a[i];
    a[i] = a[j];
    a[j] = temp;
}

static int partition(int[] a, int left, int right, int x) {
    int i;
    for (i = left; i < right; i++)
        if (a[i] == x)
            break;
    swap(a, i, right);
    i = left;
    for (int j = left; j <= right - 1; j++) {
        if(a[j] <= x) {
            swap(a, i, j);
            i++;
        }
    }
    swap(a, i, right);
    return i;
}

public static void main(String[] args) {
    int a[] = {3, 8, 1, 9, 10, 7, 6, 2, 5, 4};
    int n = a.length;
    int k = 1;
    System.out.println(medianOfMediansSelect(a, 0, n - 1, k));
}
}

Thanks in advance to everyone


Solution

  • So, I modified your median method to correct the problem. You should check Arrays.sort method for a clear understanding.

    Now it gives 6, for k=6.

    Here is it,

       static int median(int a[], int i, int n)
       {
          Arrays.sort(a, i, i + n - 1);
    
          return a[i + n / 2];
       }