The "text-book" (= what people use) version of the Merge Sort algorithm

• Summary

• Simplifying assumption that we made:

 Assume that the number of elements in the input array is a power of 2 (= 2k)

• The reason we made this assumption is the fact that:

 I did not want to deal with non-existing array indices in the merge operation (yet, I will now)

• What can go wrong in the Simplified merge algorithm ?

• I have repeated the simplified merge sort algorithm here:

 ``` public static void sort(double[] a, double[] tmp) { int width; for ( width = 1; width < a.length; width = 2*width ) { // Combine sections of array a of width "width" int i; for ( i = 0; i < a.length; i = i + 2*width ) { int left, middle, right; left = i; middle = i + width; right = i + 2*width; merge( a, left, middle, right, tmp ); } /* ================================================ Copy tmp[ ] back to a[ ] for next iteration ================================================ */ for ( i = 0; i < a.length; i++ ) a[i] = tmp[i]; } } ```

(I highlighted the part that can give us trouble)

• Example:

• Sort: array (3, 1, 4)

• Iteration 1: merge arrays of size = 1:

 ``` iter 1 uses: width = 1 The for-loop: for ( i = 0; i < a.length; i = i + 2*width ) executes as follows: iter 1: left = 0 middle = 1 right = 2 merge( a, 0, 1, 2, tmp ) +++ no problem... (Test for iter 2: (i = 2) i < a.length (= 3), OK, proceed) iter 2: left = 2 middle = 3 right = 4 merge( a, 2, 3, 4, tmp ) *** Problem: a[3] does not exist !!! ```

• The text-book version of the merge sort algorithm

• Fixing the problem is very easy:

 You just have to make sure that you do not use elements beyond a.length in the merge operation

• The text-book version (i.e., what people use in real-life) of the bottom-up merge sort algorithm:

(I have highlighted the differences in red)

 ``` public static void sort(double[] a, double[] tmp) { int width; for ( width = 1; width < a.length; width = 2*width ) { // Combine sections of array a of width "width" int i; for ( i = 0; i < a.length; i = i + 2*width ) { int left, middle, right; left = i; middle = min(i+width, a.length); right = min(i+2*width, a.length); merge( a, left, middle, right, tmp ); } /* ================================================ Copy tmp[ ] back to a[ ] for next iteration ================================================ */ for ( i = 0; i < a.length; i++ ) a[i] = tmp[i]; } } ```

Test program with non power of 2 number of elements in input array:

 ``` public static void main( String[] args ) { double[] x = {12.4, 13.9, 11.2, 10.1, 6.4, 3.5, 7.5, 2.5, 8.9, 4.2, 9.2, 1.1} ; double[] help = new double[x.length]; System.out.println("Before sort: " + Arrays.toString(x) ); MergeSort.sort( x, help ); // Merge sort System.out.println("\nAfter sort: " + Arrays.toString(x) ); } ```

Output:

 ```Before sort: [12.4, 13.9, 11.2, 10.1, 6.4, 3.5, 7.5, 2.5, 8.9, 4.2, 9.2, 1.1] After 1 iter: [12.4, 13.9, 10.1, 11.2, 3.5, 6.4, 2.5, 7.5, 4.2, 8.9, 1.1, 9.2] After 1 iter: [10.1, 11.2, 12.4, 13.9, 2.5, 3.5, 6.4, 7.5, 1.1, 4.2, 8.9, 9.2] After 1 iter: [2.5, 3.5, 6.4, 7.5, 10.1, 11.2, 12.4, 13.9, 1.1, 4.2, 8.9, 9.2] After 1 iter: [1.1, 2.5, 3.5, 4.2, 6.4, 7.5, 8.9, 9.2, 10.1, 11.2, 12.4, 13.9] After sort: [1.1, 2.5, 3.5, 4.2, 6.4, 7.5, 8.9, 9.2, 10.1, 11.2, 12.4, 13.9] ```

• Example Program: (Demo above code)

How to run the program:

 Right click on link(s) and save in a scratch directory To compile:   javac testProg.java To run:          java testProg