我正在实现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和泛型。我不知道如何进行递归合并功能。
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++];
}
}
答案 0 :(得分:0)
这是一个可能的解决方案。我不记得是否有更好的方法,因为我通常只使用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++];
}
}