合并排序java实现错误

时间:2015-06-24 06:55:23

标签: java recursion mergesort

好的,所以我试图在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

请帮我纠正这个问题...... :(

5 个答案:

答案 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;

谢谢大家的支持。我浪费了一整天试图找出这个烂摊子!