簡體   English   中英

如何在Java中使用泛型實現遞歸mergeSort?

[英]How to implement a recursive mergeSort with generics in java?

我正在實現mergeSort函數。 我了解分而治之的邏輯,但實際的合並部分使我感到困惑。 這是過去的作業問題,但我正在嘗試理解。

       /**
         * 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
         */

對於此方法,無法更改參數,公共,靜態和泛型。 我不知道如何做遞歸合並功能。

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++];
    }
}

這是一種可能的解決方案。 我不記得是否有更好的方法可以這樣做,因為我通常只使用Collections.sort()。

注意,由於原始數組的內容將被修改,因此無需返回值。

也不需要傳遞中間索引。

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++];
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM