Non-recursive implementation of Merge Sort

  • Previously, we have used the MergeSort.merge( ) method to sort an array of 4 elements as follows:

        public static void main(String[] args)
        {
            Integer[] list = {7, 3, 8, 5};
    
            Integer[] help = new Integer[list.length];      // Helper array
    
            printArray(list);
    
            // Merge arrays of 1 elements
            MergeSort.merge(list, 0, 1, 2, help);
            MergeSort.merge(list, 2, 3, 4, help);
    
            // Merge arrays of 2 elements
            MergeSort.merge(list, 0, 2, 4, help);
    
            printArray(list);
        }
    

  • (0) An array of 1 element is sorted
    (2) Merge a pair of (adjacent) array of 1 element into a sorted array of 2 elements
    (2) Merge a pair of (adjacent) array of 2 element into a sorted array of 4 elements
     

DEMO: 14-sort/10-merge-sort/Demo3.java

Non-recursive implementation of Merge Sort

  • We can use the MergeSort.merge( ) method to sort an array of 8 elements as follows:

        public static void main(String[] args)
        {
            Integer[] list = {7, 3, 2, 1, 8, 5, 4, 6};
    
            Integer[] help = new Integer[list.length];      // Helper array
    
            printArray(list);
    
            // Merge arrays of 1 elements
            MergeSort.merge(list, 0, 1, 2, help);
            MergeSort.merge(list, 2, 3, 4, help);
            MergeSort.merge(list, 4, 5, 6, help);
            MergeSort.merge(list, 6, 7, 8, help);
    
            // Merge arrays of 2 elements
            MergeSort.merge(list, 0, 2, 4, help);
            MergeSort.merge(list, 4, 6, 8, help);
    
            // Merge arrays of 4 elements
            MergeSort.merge(list, 0, 4, 8, help);
    
            printArray(list);
        }
    

  • And so on !!!

Non-recursive implementation of Merge Sort

  • The Merge Sort can be implemented without using recursion as follows:

        public static <T extends Comparable<T>> void sort(T[] A, T[] H)
        {
            int mergeSize = 1;
    
            while ( mergeSize < A.length )
            {
                int s, m, e;
    
                for (s = 0; s < A.length; s += 2*mergeSize)
                {
                    m = s + mergeSize;
                    e = Math.min(A.length, s + 2*mergeSize);
    
                        merge( A, s, m, e, H);
                }
    
                mergeSize = 2*mergeSize;
            }
        }
    

     

Non-recursive implementation of Merge Sort

  • Start merging arrays of mergeSize = 1 and double the mergeSize after each iteration:

        public static <T extends Comparable<T>> void sort(T[] A, T[] H)
        {
            int mergeSize = 1;
    
            while ( mergeSize < A.length )
            {
                int s, m, e;
    
                for (s = 0; s < A.length; s += 2*mergeSize)
                {
                    m = s + mergeSize;
                    e = Math.min(A.length, s + 2*mergeSize);
    
                        merge( A, s, m, e, H);
                }
    
                mergeSize = 2*mergeSize;
            }
        }
    

     

Non-recursive implementation of Merge Sort

  • We only need to perform merge( ) when there are > 1 piece of array half:

        public static <T extends Comparable<T>> void sort(T[] A, T[] H)
        {
            int mergeSize = 1;
    
            while ( mergeSize < A.length )
            {
                int s, m, e;
    
                for (s = 0; s < A.length; s += 2*mergeSize)
                {
                    m = s + mergeSize;
                    e = Math.min(A.length, s + 2*mergeSize);
    
                        merge( A, s, m, e, H);
                }
    
                mergeSize = 2*mergeSize;
            }
        }
    

    A[]: | mergeSize | mergeSize | mergeSize | mergeSize | .....
     

Non-recursive implementation of Merge Sort

  • The start index s of the first array are: 0, 2*mergeSize, 4*mergeSize, ...:

        public static <T extends Comparable<T>> void sort(T[] A, T[] H)
        {
            int mergeSize = 1;
    
            while ( mergeSize < A.length )
            {
                int s, m, e;
    
                for (s = 0; s < A.length; s += 2*mergeSize)
                {
                    m = s + mergeSize;
                    e = Math.min(A.length, s + 2*mergeSize);
    
                        merge( A, s, m, e, H);
                }
    
                mergeSize = 2*mergeSize;
            }
        }
    

    A[]: | mergeSize | mergeSize | mergeSize | mergeSize | .....

         s                       s  

Non-recursive implementation of Merge Sort

  • The end index m of the first array are: mergeSize, 3*mergeSize, 5*mergeSize, ... :

        public static <T extends Comparable<T>> void sort(T[] A, T[] H)
        {
            int mergeSize = 1;
    
            while ( mergeSize < A.length )
            {
                int s, m, e;
    
                for (s = 0; s < A.length; s += 2*mergeSize)
                {
                    m = s + mergeSize;
                    e = Math.min(A.length, s + 2*mergeSize);
    
                        merge( A, s, m, e, H);
                }
    
                mergeSize = 2*mergeSize;
            }
        }
    

    A[]: | mergeSize | mergeSize | mergeSize | mergeSize | .....

         s           m           s           m

Non-recursive implementation of Merge Sort

  • The end index s of the 2nd array are: 2*mergeSize, 4*mergeSize, ... unless...

        public static <T extends Comparable<T>> void sort(T[] A, T[] H)
        {
            int mergeSize = 1;
    
            while ( mergeSize < A.length )
            {
                int s, m, e;
    
                for (s = 0; s < A.length; s += 2*mergeSize)
                {
                    m = s + mergeSize;
                    e =                    s + 2*mergeSize ;
    
                        merge( A, s, m, e, H);
                }
    
                mergeSize = 2*mergeSize;
            }
        }
    

    A[]: | mergeSize | mergeSize | mergeSize | mergeSize | .....

         s           m           e/s          m          e
    Unless:   we are at the end of the input array !

Non-recursive implementation of Merge Sort

  • The end index s of the 2nd array cannot be > A.length:

        public static <T extends Comparable<T>> void sort(T[] A, T[] H)
        {
            int mergeSize = 1;
    
            while ( mergeSize < A.length )
            {
                int s, m, e;
    
                for (s = 0; s < A.length; s += 2*mergeSize)
                {
                    m = s + mergeSize;
                    e = Math.min(A.length, s + 2*mergeSize);
    
                        merge( A, s, m, e, H);
                }
    
                mergeSize = 2*mergeSize;
            }
        }
    

    A[]: | mergeSize | mergeSize | mergeSize | mergeSize | .....

         s           m           e/s          m          e       .... e = A.length

Non-recursive implementation of Merge Sort

  • Merge the 2 arrays:

        public static <T extends Comparable<T>> void sort(T[] A, T[] H)
        {
            int mergeSize = 1;
    
            while ( mergeSize < A.length )
            {
                int s, m, e;
    
                for (s = 0; s < A.length; s += 2*mergeSize)
                {
                    m = s + mergeSize;
                    e = Math.min(A.length, s + 2*mergeSize);
    
                    merge(A, s, m, e, H);
                }
    
                mergeSize = 2*mergeSize;
            }
        }
    

     

DEMO: demo/14-sort/12b-non-recursive-merge-sort/MergeSort.java + Demo.java