【发布时间】:2016-03-18 00:23:07
【问题描述】:
我在计算机课上遇到了合并排序问题。我不断收到错误或返回的原始 ArrayList。
我相信合并排序涉及递归地将数组(列表)分成两半,直到只剩下一个元素,然后从这些单独的元素开始工作,按排序顺序合并它们。这一直持续到对数组(列表)进行排序。至于实际的排序部分,我试图在新的 ArrayList 中插入两半之间的较高值,直到它们都为空,在这种情况下,填充的 ArrayList 现在已排序。
这是我当前的代码:
public static ArrayList<Integer> mergesort(ArrayList<Integer> arr) {
// Base case: if size of ArrayList is 1, return it.
if (arr.size() < 2) {
return arr;
}
// Else: Find the middle index.
int middle = (arr.size() - 1) / 2;
// Split into left and right halves.
ArrayList<Integer> leftHalf = new ArrayList<Integer>();
for (int i = 0; i < middle; i++)
leftHalf.add(arr.get(i));
ArrayList<Integer> rightHalf = new ArrayList<Integer>();
for (int j = middle; j < arr.size(); j++)
rightHalf.add(arr.get(j));
// Recurse using the halves.
mergesort(leftHalf);
mergesort(rightHalf);
// Sort and merge the two halves.
return merge(leftHalf, rightHalf, arr);
}
// Merge two halves and sort them, and put the sorted values into the ArrayList sorted.
public static ArrayList<Integer> merge(ArrayList<Integer> arr1, ArrayList<Integer> arr2, ArrayList<Integer> sorted) {
// While the ArrayLists are not empty, add sorted elements to ArrayList sorted.
while (arr1.size() > 0 && arr2.size() > 0) {
// If the first element in A is greater than the first in B, remove A and add to ArrayList sorted.
if (arr1.get(0) >= arr2.get(0)) {
sorted.add(arr1.get(0));
arr1.remove(0);
}
// Else, remove from B and add to ArrayList sorted.
else {
sorted.add(arr2.get(0));
arr2.remove(0);
}
}
// If there're still elements in A due to arr being odd
// add them to C since they will be the largest.
if (arr1.size() > 0)
sorted.add(arr1.get(0));
return sorted;
}
如果有任何帮助,我将不胜感激,但请不要给我合并排序的完整实现,因为我想真正了解如何在未来执行此操作。
【问题讨论】:
-
最简单的未正确排序的示例是什么?当您在调试器中单步执行此代码时会看到什么?
-
顺便说一句,要提高性能,请尝试这样做,不要创建任何新的
ArrayLists,也不要复制它们,也不要使用昂贵的remove(0)。 -
我总是返回原始数组,即使是简单的事情。我认为我对递归还没有扎实的掌握,所以我很难确定问题是什么。
-
如果不创建新的 ArrayList,我将如何做到这一点?我想我必须提高内存效率,因为我得到了 java.lang.OutofMemoryError
-
尝试创建一个方法
mergesort(List<Integer> list, int start, int end),它不会从列表中删除任何内容,但可以对值进行适当的排序。这不是 CPU 效率最高的,但不会产生额外的内存,尽管您可以创建一个方法mergesort(List<integer> list, int start, int end, List<Integer> scratchList),其中暂存列表用作可重用列表。这最多会使您的内存使用量增加一倍。顺便说一句,如果您可以使用int[]而不是List<Integer>这可以是内存使用量的 1/5。
标签: java arrays sorting arraylist merge