Search code examples
javaalgorithmsortingpseudocode

Converting Merge Sort pseudocode to running Java code


I tried to convert this Merge Sort pseudocode into Java but don't get the right output. Here is the pseudocode:

Merge-Sort(A, p, r )
   if p < r
     then q←(p+r)/2 
     Merge-Sort(A, p, q)
     Merge-Sort(A, q + 1, r )
     Merge(A, p, q, r )


Merge(A, p, q, r )
   for k←1 to r−p+1 do
     if j>r or (i ≤ q and A[i] ≤ A[j])
     then B[k]←A[i]; i←i+1 else B[k]←A[j];j←j+1
   for k←1 to r−p+1 do A[k+p−1]←B[k]

And this is my Java code for it:

public class MergeSort {

public static void main(String[] args) {
    int[] a = {2, 6, 3, 5, 1};
    mergeSort(a, 0, a.length - 1);
    for (int i = 0; i < a.length; i++) {
        System.out.print(" " + a[i]);
    }
}

public static void mergeSort(int[] a, int from, int to) {
    final int begin = from, end = to;
    if (begin < end) {
        final int mid = (begin + end) / 2;
        MergeSort.mergeSort(a, begin, mid);
        MergeSort.mergeSort(a,  mid+1, end);
        MergeSort.merge(a, begin, mid, end);
    }
}

private static void merge(int[] a, int from, int mid, int to) {
    final int begin = from, mitte = mid, end = to;

    int[] B = new int[a.length];

    int i = begin, j = mitte;
    for (int k = 0; k <= end-begin; k++) {
        if (j > end || (i <= mitte && a[i] <= a[j])) {
            B[k] = a[i];
            i++;
        } else {
            B[k] = a[j];
            j++;
        }
    }

    for (int k = 0; k < end-begin; k++) {
        a[k + begin] = B[k];
    }
}

Sadly it is not working like that. I think i do something wrong with some indexes but I can't figure out where exactly the error is. I need to stick as close as possible to this pseudocode. It would be great if someone could show me what I am doing wrong.


Solution

  • The pseudocode given for the Merge algorithm is somewhat incorrect because it does not say anything about the situation when only one pointer moves while other remains stationary.

    In the above mentioned case you would have to separately fill out temporary array for by moving that stationary pointer.

    Also the required length of B is to - from + 1 and it should be j = mitte + 1 instead of j = mitte The correct code for the merge is :

    private static void merge(int[] a, int from, int mid, int to) {
            final int begin = from, mitte = mid, end = to;
    
            int[] B = new int[end-begin+1];
            int k=0;
            int i = begin, j = mitte+1;
            while(i<=mid&&j<=end)
                if(a[i]<=a[j]){
                    B[k++] = a[i];
                    i++;
                } else {
                    B[k++] = a[j];
                    j++;
                }
            //in case i remained stationary
            while(i<=mid)
                B[k++] = a[i++];
    
            //in case j remained stationary
            while(j<=end)
                B[k++] = a[j++];
    
            //Now copy the array
            i=0;
            for(k=begin;k<=end;++k)
             a[k]=B[i++];
        }