在我的合并排序中获取堆栈溢出错误

时间:2012-09-29 21:22:23

标签: java algorithm

我的合并排序中出现堆栈溢出错误。不知道为什么。

//BAD CODE BAD CODE
public static void main(String[] args) {
    int[] S = {3,4,6,2,5,3,7};
    mergesort(S, 1, 5);
    System.out.println(S);
}   

public static void mergesort(int[] S, int left, int right){
    if (right <= 1) { return; }
    int mid = (right + left) / 2;
    mergesort (S, left, mid);
    mergesort (S, mid+1, right);
    merge(S, left, mid, right); 
}

public static void merge(int[] S, int left, int mid, int right){
    int i, j;
    int[] aux = new int[S.length];

    for (i = mid+1; i > left; i--) {aux[i-1] = S[i-1];}
    for (j = mid; j < right; j++) {aux[right+mid-j] = S[j+1];}
    for (int k = left; k <= right; k++){
        if (aux[j] < aux[i]) {
            S[k] = aux[j--]; 
        } else{
            S[k] = aux[i++];
        }
    }
}
//END OF BAD CODE

更新

感谢所有快速回复,我让它工作并做了一些建议的更改。复制并粘贴,试一试:

//GOOD CODE
package longest_sequence_proj;
import java.util.*;

public class MergeTest {

/**
 * @param args
 */
public static void main(String[] args) {
    int[] S = {3,4,6,2,5,3,7};

    mergesort(S, 0, 6);

    System.out.println(Arrays.toString(S));

}



public static void mergesort(int[] S, int left, int right){
    if (right <= left) { return; }
    int mid = (right + left) / 2;
    mergesort (S, left, mid);
    mergesort (S, mid+1, right);
    merge(S, left, mid, right);

    }

public static void merge(int[] S, int left, int mid, int right){
    int i, j;
    int[] aux = new int[S.length];

    for (i = mid+1; i > left; i--) {aux[i-1] = S[i-1];}
    for (j = mid; j < right; j++) {aux[right+mid-j] = S[j+1];}
    for (int k = left; k <= right; k++){
        if (aux[j] < aux[i]) {
            S[k] = aux[j--]; 
        } else{
            S[k] = aux[i++];
        }
    }
}
}

3 个答案:

答案 0 :(得分:3)

你的停止条款错了:

 if (right <= 1) { return; }

当你使用的部分数组的 size 小于1时,你真的想要停止,所以你可能正在寻找:

if (right - left <= 1) { return; }

作为旁注:

System.out.println(S);

我想这不是你想要的(它不打印数组,而是打印对象的标识符......)
为了打印阵列,请使用:

System.out.println(Arrays.toString(S));

答案 1 :(得分:1)

好吧,考虑一下:

int mid = (right + left) / 2;
...
mergesort (S, mid+1, right);

从left = 1和right = 5开始,mid变为3,因此递归调用left = 4且right = 5。这得到mid = 9/2,我猜java中是4,所以我们得到另一个递归,其中left = 5和right = 5,这导致mid = 5,并且对于left = 6和right = 5的递归,依此类推。 “正确”永远不会变得更小......

答案 2 :(得分:0)

mergesort来电的正确分支永远不会结束。

您的停止条件为right <= 1 - 但在您的呼叫树right的右侧分支上永远不会是1

你应该为你的递归设置一个更好的结束条件 - 实际上会在某个时候结束。