[英]What is wrong with my Merge Sort code?
I'm having trouble with Merge Sort in my computers class. 我的计算机课上的合并排序出现问题。 I keep getting either errors or the original ArrayList returned. 我一直收到错误或返回原始ArrayList。
I believe that Merge Sort involves splitting an array(list) in half recursively until there is only one element left, then, working from those individual elements, merging them in sorted order. 我认为,合并排序涉及将数组(列表)递归拆分为一半,直到只剩下一个元素,然后从这些单独的元素开始工作,将它们按排序顺序合并。 This continues until the array(list) has been sorted. 这一直持续到对数组(列表)进行排序为止。 As for the actual sorting part, I am trying to insert into a new ArrayList the higher value between the two halves until they are both empty, in which case the filled ArrayList is now sorted. 至于实际的排序部分,我试图将新的两半之间的较高值插入到新的ArrayList中,直到它们都为空为止,在这种情况下,现在对填充的ArrayList进行排序。
Here's my current code: 这是我当前的代码:
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;
}
I would appreciate any help, but please don't give me a full implementation of the Merge Sort, since I want to actually learn how to do this for the future. 我将不胜感激,但是请不要给我完整的“合并排序”实现,因为我想实际学习将来如何做。
Two immediate problems I see. 我看到了两个迫在眉睫的问题。
First, you have infinite recursion. 首先,您具有无限递归。 Say you pass in a 4-value list and print your list size and middle values, you'll get: 假设您传递一个4值列表并打印列表大小和中间值,您将获得:
size 4, middle 1 size 3, middle 1 size 2, middle 0 size 2, middle 0 size 2, middle 0 ... to infinity
Remember that Java is aleardy doing integer division in your code. 请记住,Java在代码中执行整数除法已相当可行。
Second, you're passing the arr
parameter from mergesort
to merge
, nothing is ever getting removed from it. 其次,您要将arr
参数从mergesort
到merge
,因此什么也不会被删除。 So even if you made it past the infinite recursion you'd still end up with a larger list in the end, your original list plus anything you've .add()
ed to it 因此,即使您经过了无限递归,您最终还是会得到一个更大的列表,这是原始列表以及您已经.add()
编辑的任何内容
As mentioned by MarquisDeMizzle, so that middle == 1 when arr.size() == 1. 正如MarquisDeMizzle提到的那样,当arr.size()== 1时,中间== 1。
int middle = arr.size() / 2;
After main merge loop copy any remaining elements, and since you don't know if arr1 or arr2 go empty first, check both: 在主合并循环之后,复制所有剩余元素,并且由于您不知道arr1或arr2首先变空,因此请同时检查以下两项:
// copy any remaining elements
while (arr1.size() > 0)
sorted.add(arr1.get(0));
while (arr2.size() > 0)
sorted.add(arr2.get(0));
If interested, you might want to learn bottom up merge sort. 如果有兴趣,您可能想学习自下而上的合并排序。 It skips all the recursion and just starts off assuming an array with n elements is n runs of size 1, just using indexing to do the merge back and forth between the original and a temporary array. 它会跳过所有递归操作,并假设包含n个元素的数组的大小为n次运行,并且只是使用索引在原始数组和临时数组之间来回合并,就开始了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.