简体   繁体   中英

How to implement a recursive mergeSort with generics in java?

I'm implementing a mergeSort function. I understand the logic of divide and conquer, but the actual merging part is confusing me. This is a past homework problem, but I'm trying to understand it.

       /**
         * Implement merge sort.
         *
         * It should be:
         * stable

         * Have a worst case running time of:
         *  O(n log n)
         *
         * And a best case running time of:
         *  O(n log n)
         *
         * You can create more arrays to run mergesort, but at the end,
         * everything should be merged back into the original T[]
         * which was passed in.
         *
         * ********************* IMPORTANT ************************
         * FAILURE TO DO SO MAY CAUSE ClassCastException AND CAUSE
         * YOUR METHOD TO FAIL ALL THE TESTS FOR MERGE SORT
         * ********************************************************
         *
         * Any duplicates in the array should be in the same relative position      
         * after sorting as they were before sorting.
         *
         * @throws IllegalArgumentException if the array or comparator is null
         * @param <T> data type to sort
         * @param arr the array to be sorted
         * @param comparator the Comparator used to compare the data in arr
         */

For this method, the parameters, public, static, and generics can't be changed. I don't know how to do the recursive merge function.

public static <T> void mergesort(T[] arr, Comparator<T> comparator) {
    if (arr == null || comparator == null) {
        throw new IllegalArgumentException("Null arguments were passed.");
    }
    if (arr.length >= 2) {
        //Midpoint from which we will split the array.
        int middle = arr.length / 2;
        //Each half of the split array
        T[] left = (T[]) new Object[middle];
        T[] right = (T[]) new Object[arr.length - middle];
        //Copy items from original into each half
        for (int i = 0; i < middle; i++) {
            left[i] = arr[i];
        }
        for (int i = middle; i < length; i++) {
            right[i] = arr[i];
        }
        //Keep splitting until length is 1
        mergesort(left, comparator);
        mergesort(right, comparator);
        //merge each array back into original which would now be sorted.
        merge(left, right, middle, arr, comparator);
        merge(right, middle, arr, comparator);

    }

}

private static <T> T[] merge(T[] left, T[] right, int middle, T[] arr,
                             Comparator<T>
        comparator) {
    int i = 1, j = middle + 1, k = 1;
    while (i <= middle && j <= arr.length) {
        arr[k++] = (comparator.compare(arr[k], partioned[i]) < 0)
                ? arr[j++] : partioned[i++];
    }
    while (i <= middle) {
        arr[k++] = partioned[k++];
    }
}

Here's one possible solution. I don't remember if there's a better way to do this, since I generally just use Collections.sort().

Note that there's no need to return a value, since the contents of the original array are going to be modified.

There's also no need to pass in the middle index.

private static <T> void merge(T[] left, T[] right, T[] dest) {
  if (left.length + right.length != dest.length)
    throw new IllegalArgumentException(
                    "left length + right length must equal destination length");
  int leftIndex = 0;
  int rightIndex = 0;
  int destIndex = 0;
  while (destIndex < dest.length) {
    if (leftIndex >= left.length) //no more entries in left array, use right
      dest[destIndex++] = right[rightIndex++];
    else if (rightIndex >= right.length) // no more entries in right array, use left
      dest[destIndex++] = left[leftIndex++];
    else if (left[leftIndex] < right[rightIndex]) //otherwise pick the lower value
      dest[destIndex++] = left[leftIndex++];
    else 
      dest[destIndex++] = right[rightIndex++];
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM