我正在做一个学校项目,我必须编写一个执行合并排序的程序。 mergeSort()
方法是递归的,并导致堆栈溢出错误。我知道如果递归方法不断地继续下去会发生这种情况,但是我无法弄清楚代码中的什么使它无法停止。
任何帮助将不胜感激。
这是代码(如果我的教授提供了一个Sort.java
程序,则可以解释为什么没有main
方法)。
public class Merge {
/**
* Sort an array, in-place, using merging.
* @param array The array to be sorted.
* POSTCONDITION: The elements of array are in ascending order.
*/
public static void sort(int[] array) {
int[] tempArray = mergeSort(array);
for (int i = 0; i < tempArray.length; i++) {
array[i] = tempArray[i];
}
}
/**
* Extract the portion of an array from start up to (excluding) stop.
* @param array The source array.
* @param start The starting index (inclusive).
* @param stop The ending index (exclusive).
* @return An array containing the same elements the portion of array.
* PRECONDITION: 0 <= start <= stop <= array.length
*/
private static int[] subarray(int[] array, int start, int stop) {
int[] newArray = new int[stop-start];
for (int i = 0; i < newArray.length; i++) {
newArray[i] = array[start + i];
}
return newArray;
}
/**
* Merge two sorted arrays into one new array.
* @param first The first array, already sorted.
* @param second The second array, already sorted.
* @return A new array containing the elements of first and second,
* in order.
*/
private static int[] merge(int[] first, int[] second) {
int[] newArray = new int[first.length + second.length];
int count = 0;
int i = 0;
int j = 0;
while ((i < first.length) || (j < second.length)) {
if ((i < first.length) && (j < second.length)) {
if (first[i] < second[j]) {
newArray[count++] = first[i++];
} else {
newArray[count++] = second[j++];
}
} else if (j < second.length) {
newArray[count++] = second[j++];
} else if (i < first.length) {
newArray[count++] = first[i++];
}
}
return newArray;
}
/**
* Sort an array by merging.
* @param array The array to sort.
* @return A new array containing the elements of array, in order.
*/
private static int[] mergeSort(int[] array) {
int split = 0;
if (array.length < 2) {
return array;
} else {
split = array.length%2;
int[] array1 = mergeSort(subarray(array, 0, split));
int[] array2 = mergeSort(subarray(array, split, array.length));
return merge(array1, array2);
}
}
}
答案 0 :(得分:3)
我假设split = array.length%2;
应该是split = array.length/2;
如果数组的长度为偶数,则将花费一些时间,因为第二个子数组将有效地等于原始数组,并且您将获得无限递归。使用奇数长度的数组,第二个子数组将为偶数长度,并且您再次获得无限递归。
要调试无限递归,请首先使用printf
语句检查递归之前发生的事情 (因为这可能是问题所在),以确保递归是按计划进行,例如:
split = array.length%2;
System.err.printf(
"%d broken into %d (%d to just before %d) and %d (%d to just before %d).\n",
array.length, split, 0, split, array.length - split, split, array.length);
int[] array1 = mergeSort(subarray(array, 0, split));
int[] array2 = mergeSort(subarray(array, split, array.length));
return merge(array1, array2);
看看事情是否以应有的方式变小。