Sorting Algorithm Tutorials - Herong's Tutorial Examples - 6.12, by Herong Yang
Merge Sort - Implementation Improvements
This section provides a tutorial on how to improve the performance of the Merge Sort implementation by dividing data elements into 3 sections.
One way to improve the performance is to divide data elements into 3 sections. Sort them separately, then merge them. Merging 3 sorted sections is more efficient than merging 2 sections. Here my improved implementation:
/* HyArrays.java * This class contains sorting methods similar to java.util.Arrays.sort(). * All sorting methods should have a signature of * %Sort(Object[] a, int fromIndex, int toIndex) * where "fromIndex" is inclusive, and "toIndex" is exclusive. * Copyright (c) 2011 HerongYang.com. All Rights Reserved. */ public class HyArrays { public static void mergeSort3(HyObject[] a, int fromIndex, int toIndex) { HyObject[] b = new HyObject[toIndex]; for (int i=fromIndex; i<toIndex; i++) { b[i] = a[i]; } mergeSortInternal3(b, a, fromIndex, toIndex); } private static void mergeSortInternal3(HyObject[] a, HyObject[] b, int fromIndex, int toIndex) { if (toIndex-fromIndex<=1) { return; } else if (toIndex-fromIndex==2) { if ((a[fromIndex]).compareTo(a[toIndex-1])>0) { b[toIndex-1] = a[fromIndex]; b[fromIndex] = a[toIndex-1]; } } else { int iLeft = (toIndex-fromIndex)/3 + fromIndex; int iRight = (toIndex-iLeft)/2 + iLeft; mergeSortInternal3(b,a,fromIndex,iLeft); mergeSortInternal3(b,a,iLeft,iRight); mergeSortInternal3(b,a,iRight,toIndex); int iFirst = fromIndex; int iSecond = iLeft; int iThird = iRight; int i = fromIndex; while (iFirst<iLeft && iSecond<iRight && iThird<toIndex) { if ((a[iFirst]).compareTo(a[iSecond])<0) { if ((a[iFirst]).compareTo(a[iThird])<0) { b[i] = a[iFirst]; iFirst++; } else { b[i] = a[iThird]; iThird++; } } else { if ((a[iSecond]).compareTo(a[iThird])<0) { b[i] = a[iSecond]; iSecond++; } else { b[i] = a[iThird]; iThird++; } } i++; } while (iFirst<iLeft && iSecond<iRight) { if ((a[iFirst]).compareTo(a[iSecond])<0) { b[i] = a[iFirst]; iFirst++; } else { b[i] = a[iSecond]; iSecond++; } i++; } while (iSecond<iRight && iThird<toIndex) { if ((a[iSecond]).compareTo(a[iThird])<0) { b[i] = a[iSecond]; iSecond++; } else { b[i] = a[iThird]; iThird++; } i++; } while (iThird<toIndex && iFirst<iLeft) { if ((a[iFirst]).compareTo(a[iThird])<0) { b[i] = a[iFirst]; iFirst++; } else { b[i] = a[iThird]; iThird++; } i++; } while (iFirst<iLeft) { b[i] = a[iFirst]; iFirst++; i++; } while (iSecond<iRight) { b[i] = a[iSecond]; iSecond++; i++; } while (iThird<toIndex) { b[i] = a[iThird]; iThird++; i++; } } } }
Performance was indeed improved:
Array size: 100000 Average sorting time: 14 milliseconds Number of tests: 1000 Performance: 0.14 O(N) microseconds Performance: 0.008428839878591473 O(N*Log2(N)) microseconds Performance: 1.4E-6 O(N*N) microseconds Array size: 200000 Average sorting time: 43 milliseconds Number of tests: 1000 Performance: 0.215 O(N) microseconds Performance: 0.012209221438229055 O(N*Log2(N)) microseconds Performance: 1.075E-6 O(N*N) microseconds Array size: 300000 Average sorting time: 84 milliseconds Number of tests: 1000 Performance: 0.28 O(N) microseconds Performance: 0.015389178889052897 O(N*Log2(N)) microseconds Performance: 9.333333333333333E-7 O(N*N) microseconds
Please also note that merge sort requires a working array to do the merge. Another direction of improving this implementation is to try to reduce or eliminate the working array.
In case you are using older versions of Java that support only the raw "Comparable" interface type, here is my old implementation:
/* HyArrays.java * This class contains sorting methods similar to java.util.Arrays. * All sorting methods should have a signature of * %Sort(Object[] a, int fromIndex, int toIndex) * where "fromIndex" is inclusive, and "toIndex" is exclusive. * Copyright (c) 2011 HerongYang.com. All Rights Reserved. */ public class HyArrays { public static void mergeSort3(Object[] a, int fromIndex, int toIndex) { Object[] b = new Object[toIndex]; for (int i=fromIndex; i<toIndex; i++) { b[i] = a[i]; } mergeSortInternal3(b, a, fromIndex, toIndex); } private static void mergeSortInternal3(Object[] a, Object[] b, int fromIndex, int toIndex) { if (toIndex-fromIndex<=1) { return; } else if (toIndex-fromIndex==2) { if (((Comparable)a[fromIndex]).compareTo(a[toIndex-1])>0) { b[toIndex-1] = a[fromIndex]; b[fromIndex] = a[toIndex-1]; } } else { int iLeft = (toIndex-fromIndex)/3 + fromIndex; int iRight = (toIndex-iLeft)/2 + iLeft; mergeSortInternal3(b,a,fromIndex,iLeft); mergeSortInternal3(b,a,iLeft,iRight); mergeSortInternal3(b,a,iRight,toIndex); int iFirst = fromIndex; int iSecond = iLeft; int iThird = iRight; int i = fromIndex; while (iFirst<iLeft && iSecond<iRight && iThird<toIndex) { if (((Comparable)a[iFirst]).compareTo(a[iSecond])<0) { if (((Comparable)a[iFirst]).compareTo(a[iThird])<0) { b[i] = a[iFirst]; iFirst++; } else { b[i] = a[iThird]; iThird++; } } else { if (((Comparable)a[iSecond]).compareTo(a[iThird])<0) { b[i] = a[iSecond]; iSecond++; } else { b[i] = a[iThird]; iThird++; } } i++; } while (iFirst<iLeft && iSecond<iRight) { if (((Comparable)a[iFirst]).compareTo(a[iSecond])<0) { b[i] = a[iFirst]; iFirst++; } else { b[i] = a[iSecond]; iSecond++; } i++; } while (iSecond<iRight && iThird<toIndex) { if (((Comparable)a[iSecond]).compareTo(a[iThird])<0) { b[i] = a[iSecond]; iSecond++; } else { b[i] = a[iThird]; iThird++; } i++; } while (iThird<toIndex && iFirst<iLeft) { if (((Comparable)a[iFirst]).compareTo(a[iThird])<0) { b[i] = a[iFirst]; iFirst++; } else { b[i] = a[iThird]; iThird++; } i++; } while (iFirst<iLeft) { b[i] = a[iFirst]; iFirst++; i++; } while (iSecond<iRight) { b[i] = a[iSecond]; iSecond++; i++; } while (iThird<toIndex) { b[i] = a[iThird]; iThird++; i++; } } } }
Table of Contents
Introduction of Sorting Algorithms
Java API for Sorting Algorithms
Insertion Sort Algorithm and Java Implementation
Selection Sort Algorithm and Java Implementation
Bubble Sort Algorithm and Java Implementation
Quicksort Algorithm and Java Implementation
►Merge Sort Algorithm and Java Implementation
Merge Sort - Algorithm Introduction
Merge Sort - Java Implementation
►Merge Sort - Implementation Improvements
Heap Sort Algorithm and Java Implementation
Shell Sort Algorithm and Java Implementation
Sorting Algorithms Implementations in PHP
Sorting Algorithms Implementations in Perl
Sorting Algorithms Implementations in Python