Прежде всего, я просто хочу сказать, что это вопрос домашней работы, на который я совершил множество попыток.Ошибка переполнения стека с помощью Quicksort и медианы реализации
меня попросили изменить в Java быстрой сортировки, чтобы установить стержень как псевдо медианы 9 значений в массиве, используя формулу i * (n-1) /8
Я написал computeMedian
метод, который принимает 3 целых числа, определяет высокий, и затем возвращает это значение.
Код:
public static int computeMedian(int x, int y, int z)
{
if((x >= y && x <= z) || (x >= z && x <= y)) {return x;}
else if((y >= x && y <= z) || (y >= z && y <= x)) {return y;}
else if((z >= x && z <= y) || (z >= y && z <= x)) {return z;}
else { return 0; }
}
Затем я использовал его в моем findPivot
метод, который принимает текущие array, from, to
значения и использует их, чтобы построить сводную
Вот этот код:
public static int findPivot(int[] a, int from, int to)
{
if(a.length <= 7)
{
return a[(to)/2];
}
else if(a.length > 7 && a.length <= 40)
{
return computeMedian(a[from], a[(to)/2] , a[to]);
}
else
{
int x = computeMedian(a[0 * (to)/8], a[1 * (to)/8], a[2 * (to)/8]);
int y = computeMedian(a[3 * (to)/8], a[4 * (to)/8], a[5 * (to)/8]);
int z = computeMedian(a[6 * (to)/8], a[7 * (to)/8], a[8 * (to)/8]);
return computeMedian(x,y,z);
}
}
Этот метод отлично работает для сортировки любого массива, который меньше или равен размеру 40, но как только он становится больше 40, я получаю ошибку переполнения стека возвращаясь к моему методу computeMedian
в части else {}
. Отмечу, что return computeMedian(a[from], a[(to)/2] , a[to]);
работает в разделе> 40, если я его там помещаю, но это только медиана из 3 значений, а не медиана медианы 3-х наборов.
В настоящее время это, как я findPivot
подключен к методу быстрой сортировки разделов:
private static int modPartition(int[] a, int from, int to)
{
int pivot = findPivot(a, from, to);
int i = from - 1;
int j = to + 1;
while(i < j)
{
i++; while (a[i] < pivot) { i++; }
j--; while (a[j] > pivot) { j--; }
if (i < j) { swap(a, i, j); }
}
return j;
}
Я довольно много озадачен, почему мой computeMedian
метод не работает на больших наборов данных. Я попытался помещать значения i * (n-1)/8
в массив через цикл for, сортируя их и возвращая значение в середине, а также помещая значения в массив p
и вызывая computeMedian(computeMedian(p[0], p[1], p[2]), computeMedian(p[3],p[4],p[5]),...etc
, и я получаю одну и ту же проблему переполнения стека, но она имеет тенденцию перемещаться в разные части моего кода и вести меня по кругу.
Я могу опубликовать любые дополнительные фрагменты, если кому-то нужно, но я думаю, что моя проблема здесь прямо здесь.
Спасибо за помощь. Я все еще участвую, и я думаю, что захват этого полностью поможет мне решить проблему в будущем самостоятельно.
Вот проблемные строки из трассировки стека: Line 16: int p = modPartition(a, from, to);
Линия 18 modSort(a, p+1, to);
Линия 23 int pivot = findPivot(a, from, to);
Heres мой весь метод modSort также:
public static void modSort(int[]a, int from, int to)
{
if(from >= to) { return; }
int p = modPartition(a, from, to);
modSort(a, from, p);
modSort(a, p+1, to);
}
Извините, я не читал весь текст, но ни один из добавленного вами кода не выполняет рекурсивный вызов, насколько я могу видеть, поэтому они не могут вызвать переполнение стека. Что такое сообщение об ошибке и трассировка стека при возникновении ошибки? – Andreas
@Andreas Bluej говорит мне java.lang.StackOverflowError: нулевой трассировки стека: 'java.lang.StackOverflowError \t в BMQuicksorter.modPartition (BMQuicksorter.java:23) \t в BMQuicksorter.modSort (BMQuicksorter.java: 16) \t в BMQuicksorter.modSort (BMQuicksorter.java:18) \t в BMQuicksorter.modSort (BMQuicksorter.java:18) \t в BMQuicksorter.modSort (BMQuicksorter.java:18) ' я добавлю какие строки эти находятся в исходном сообщении – Habitat
Попробуйте установить точку останова для этого конкретного исключения. – Javier