我正在尝试在Java中创建一个简单的合并排序程序。我觉得它应该可以工作,但是当我去运行它时,我得到一个堆栈溢出错误:
Stack overflow at MergeSort.mergeSort(MergeSort.java:24)
我看到其他几个人在这方面有类似的问题,但我正在努力修复我的问题。任何帮助,将不胜感激。
主要代码:
import static java.lang.System.*;
import java.util.Arrays;
public class MergeSort {
private static int passCount;
public static void mergeSort(Comparable[] list)
{
passCount = 0;
mergeSort(list, 0, list.length);
}
private static void mergeSort(Comparable[] list, int front, int back) //O( Log N )
{
int mid = (front + back) / 2;
if (mid == front)
return;
mergeSort(list, front, mid);
mergeSort(list, front, back);
merge(list, front, back);
}
private static void merge(Comparable[] list, int front, int back) //O(N)
{
Comparable[] temp = new Comparable[back - front];
int i = front;
int j = (front + back) / 2;
int k = 0;
int mid = j;
while (i < mid && j < back)
{
if (list[i].compareTo(list[j]) < 0)
{
temp[k] = list[i];
k++; i++;
}
else
{
temp[k] = list[j];
k++; i++;
}
while(i < mid)
{
temp[k++] = list[i++];
}
while (j < back)
{
temp[k++] = list[j++];
}
for (i = 0; i < back - front; ++i)
{
list[front + i] = temp[i];
}
out.println("pass " + passCount++ + " " + Arrays.toString(list) + "\n");
}
}
}
我的跑步者:
public class MergeSortRunner
{
public static void main(String args[])
{
MergeSort.mergeSort(new Comparable[]{ 9, 5, 3, 2 });
System.out.println("\n");
MergeSort.mergeSort(new Comparable[]{ 19, 52, 3, 2, 7, 21 });
System.out.println("\n");
MergeSort.mergeSort(new Comparable[]{ 68, 66, 11, 2, 42, 31});
System.out.println("\n");
}
}
答案 0 :(得分:2)
您需要更改:
mergeSort(list, front, back);
要:
mergeSort(list, mid, back);
它会导致对mergeSort
的无限通话,因为您不会在通话之间更改任何输入参数。
您可能还想要改变:
if(mid==front) return;
为:
if(back - front <= 1) return;
此外,您对此算法的实施选择可能会导致非稳定排序,因为您正在修改列表。一个更好的选择是让mergeSort
返回一个列表,列出你正在排序的内容,然后实现merge
以将两个列表作为参数,然后生成一个合并的列表。
答案 1 :(得分:0)
尝试更改
if(mid==front) return;
到
if(back-front<=1) return;
答案 2 :(得分:0)
我知道这真的很晚,但是我在寻找正确的答案!
import static java.lang.System.*;
import java.util.Arrays;
public class MergeSort{
private static int passCount;
public static void mergeSort(int[] list)
{
passCount=0;
mergeSort(list, 0, list.length);
}
private static void mergeSort(int[] list, int front, int back) //O( Log N )
{
int mid = (front+back)/2;
if(mid==front) return;
mergeSort(list, front, mid);
mergeSort(list, mid, back);
merge(list, front, back);
}
private static void merge(int[] list, int front, int back) //O(N)
{
int dif = back-front;
int[] temp = new int[dif];
int beg = front, mid = (front+back)/2;
int saveMid = mid;
int spot = 0;
while(beg < saveMid && mid < back) {
if(list[beg] < list[mid]) {
temp[spot++] = list[beg++];
} else {
temp[spot++] = list[mid++];
}
}
while(beg < saveMid)
temp[spot++] = list[beg++];
while(mid < back)
temp[spot++] = list[mid++];
for(int i = 0; i < back-front; i++) {
list[front+i] = temp[i];
}
System.out.println("pass " + passCount++ + " " + Arrays.toString(list) + "\n");
}
}
这是跑步者:
public class MergeSortRunner {
public static void main(String[] args) {
MergeSort.mergeSort(new int[]{9,5,3,2});
System.out.println();
MergeSort.mergeSort(new int[]{19,52,3,2,7,21});
System.out.println();
MergeSort.mergeSort(new int[]{68,66,11,2,42,31});
System.out.println();
}
}
事实证明,使用while循环遍历列表可以帮助您返回正确的值!
答案 3 :(得分:-3)
尽量不要递归。由于mergeSort
调用自身的事实,如果发生这种情况,则会出现堆栈溢出。