簡體   English   中英

在我的合並排序中獲取堆棧溢出錯誤

[英]Getting a stack overflow error in my Merge Sort

我在合並排序中遇到堆棧溢出錯誤。 不知道為什么。

//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++];
        }
    }
}
}

你的stop子句錯了:

 if (right <= 1) { return; }

當你使用的部分數組的大小小於1時,你實際上想要停止,所以你可能正在尋找:

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

作為旁注:

System.out.println(S);

我想這不是你想要的(它不打印數組,而是對象的標識符...)
要打印數組使用:

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

好吧,考慮一下:

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的遞歸,依此類推。 “正確”永遠不會變得更小......

mergesort調用的右分支將永遠不會結束。

你的停止條件是right <= 1 - 但是在你的調用樹的右邊分支上, right永遠不會是1

你應該在你的遞歸上設置一個更好的結束條件 - 實際上會在某個時候結束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM