我的合并排序中出现堆栈溢出错误。不知道为什么。
//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++];
}
}
}
}
答案 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
。
你应该为你的递归设置一个更好的结束条件 - 实际上会在某个时候结束。