好的,所以我试图在java中实现合并排序,但是我在分裂数组时遇到以下错误:
Exception in thread "main" java.lang.IllegalArgumentException: 2 > 1
at java.util.Arrays.copyOfRange(Arrays.java:3591)
at MergeSortS.recMergeSort(MergeSortS.java:26)
at MergeSortS.recMergeSort(MergeSortS.java:28)
at MergeSortS.mergeSort(MergeSortS.java:17)
at MergeSortM.main(MergeSortM.java:16)
Java Result: 1
BUILD SUCCESSFUL (total time: 1 second)
我的代码段如下,请帮我识别我的问题...... :(
我故意在最后评论recMergeSort(right)
递归电话,因为我想更正recMergeSort(left)
电话......
public void recMergeSort(int[] tempArray){
if(tempArray.length>1){
int mid=(tempArray.length)/2;
int[] left=Arrays.copyOfRange(tempArray,0,mid);
int[] right=Arrays.copyOfRange(tempArray,mid+1,tempArray.length-1);
recMergeSort(left);
//recMergeSort(array, right, mid+1, right.length-1);
}
}
修改
好的,所以我检查了另一个站点和copyOfRange
方法上的javadoc,需要以下内容:
Parameters:
original - the array from which a range is to be copied
from - the initial index of the range to be copied, **inclusive**
to - the final index of the range to be copied, **exclusive**. (This index may lie outside the array.)
修好后如下:
public void recMergeSort(int[] tempArray){
if(tempArray.length>1){
int mid=(tempArray.length)/2;
int[] left=Arrays.copyOfRange(tempArray,0,mid+1);
int[] right=Arrays.copyOfRange(tempArray,mid+1,tempArray.length);
recMergeSort(left);
//recMergeSort(array, right, mid+1, right.length-1);
}
}
我收到以下错误:
Exception in thread "main" java.lang.StackOverflowError
请帮我纠正这个问题...... :(
答案 0 :(得分:2)
您似乎陷入了Arrays.copyOfRange()
方法的困境。请尝试使用此代码:
public void recMergeSort(int[] tempArray){
if (tempArray.length > 1 ){
int mid=(tempArray.length)/2; // mid = 2
int[] left = Arrays.copyOfRange(tempArray, 0, mid); // [10, 20]
int[] right = Arrays.copyOfRange(tempArray, mid, tempArray.length); // [30, 40, 50]
recMergeSort(left);
//recMergeSort(array, right, mid+1, right.length-1);
}
}
Arrays.copyOfRange(array, lowIndex, highIndex)
将复制lowIndex
包含和highIndex
独占的访问权限。这意味着左侧副本的highIndex
应与相同与正确副本的lowIndex
相同。
<强>用法:强>
int[] tempArray = new int[] {10, 20, 30, 40, 50};
recMergeSory(tempArray);
答案 1 :(得分:1)
我认为太多的递归。来自Java documentation。
因应用程序递归而发生堆栈溢出时抛出 太深了。
顺便说一下:看看当tempArray.length
等于2
时会发生什么。
我认为您的代码存在错误。
int mid=(tempArray.length)/2; //mid equals 1
//calls with params tempArray, 0, 2
int[] left=Arrays.copyOfRange(tempArray,0,mid+1);
//calls with params tempArray, 2, 2
int[] right=Arrays.copyOfRange(tempArray,mid+1,tempArray.length);
最后一行是问题所在。长度为2,第二个参数为2,第三个参数为2.返回数组的长度为0.
答案 2 :(得分:1)
你得到java.lang.StackOverflowError的原因是因为你的左数组永远不会变成大小为1的数组。如果它输入if块那么它意味着mid最小值将为1,因为tempArray可以是2来满足它。然后当你复制到左边0-2时,你将所有元素再次复制到左边,右边是空的
答案 3 :(得分:0)
堆栈溢出是一个问题,因为每次调用recMergeSort都会创建两个新数组。这称为log(n)次,并导致堆栈变满。
要修复此问题,您可以增加堆栈大小(请参阅:What is the maximum depth of the java call stack?),也可以通过将recMergeSort(int[] tempArray)
的参数更改为recMergeSort(int[] unSortedArray, int startIndex, int endIndex)
来重构代码以使用就地排序。
为清楚起见:首先调用recMergeSort(array, 0, array.length-1)
,然后调用recMergeSort(array, startIndex, endIndex/2)
和recMergeSort(array, (endIndex/2)+1, endIndex)
答案 4 :(得分:0)
在考虑了你指出的所有错误之后,我通过更改以下内容以及对OP的编辑来实现它:
int mid=(tempArray.length-1)/2;
谢谢大家的支持。我浪费了一整天试图找出这个烂摊子!