001: import java.util.*;
002: 
003: /**
004:    This class carries out the merge sort algorithm.
005: */
006: public class MergeSorter
007: {
008:    /**
009:       Sorts an array, using the merge sort algorithm.
010:       @param a the array to sort
011:       @param comp the comparator to compare array elements
012:    */
013:    public static <E> void sort(E[] a, Comparator<? super E> comp)
014:    {
015:       mergeSort(a, 0, a.length - 1, comp);
016:    }
017: 
018:    /**
019:       Sorts a range of an array, using the merge sort
020:       algorithm.
021:       @param a the array to sort
022:       @param from the first index of the range to sort
023:       @param to the last index of the range to sort
024:       @param comp the comparator to compare array elements
025:    */
026:    private static <E> void mergeSort(E[] a, int from, int to,
027:       Comparator<? super E> comp)
028:    {
029:       if (from == to) return;
030:       int mid = (from + to) / 2;
031:       // Sort the first and the second half
032:       mergeSort(a, from, mid, comp);
033:       mergeSort(a, mid + 1, to, comp);
034:       merge(a, from, mid, to, comp);
035:    }
036: 
037:    /**
038:       Merges two adjacent subranges of an array
039:       @param a the array with entries to be merged
040:       @param from the index of the first element of the
041:          first range
042:       @param mid the index of the last element of the
043:          first range
044:       @param to the index of the last element of the
045:          second range
046:       @param comp the comparator to compare array elements
047:    */
048:    private static <E> void merge(E[] a,
049:       int from, int mid, int to, Comparator<? super E> comp)
050:    {
051:       int n = to - from + 1;
052:          // Size of the range to be merged
053: 
054:       // Merge both halves into a temporary array b
055:       Object[] b = new Object[n];
056: 
057:       int i1 = from;
058:          // Next element to consider in the first range
059:       int i2 = mid + 1;
060:          // Next element to consider in the second range
061:       int j = 0;
062:          // Next open position in b
063: 
064:       // As long as neither i1 nor i2 past the end, move
065:       // the smaller element into b
066:       while (i1 <= mid && i2 <= to)
067:       {
068:          if (comp.compare(a[i1], a[i2]) < 0)
069:          {
070:             b[j] = a[i1];
071:             i1++;
072:          }
073:          else
074:          {
075:             b[j] = a[i2];
076:             i2++;
077:          }
078:          j++;
079:       }
080: 
081:       // Note that only one of the two while loops
082:       // below is executed
083: 
084:       // Copy any remaining entries of the first half
085:       while (i1 <= mid)
086:       {
087:          b[j] = a[i1];
088:          i1++;
089:          j++;
090:       }
091: 
092:       // Copy any remaining entries of the second half
093:       while (i2 <= to)
094:       {
095:          b[j] = a[i2];
096:          i2++;
097:          j++;
098:       }
099: 
100:       // Copy back from the temporary array
101:       for (j = 0; j < n; j++)
102:          a[from + j] = (E) b[j];
103:    }
104: }