#java #quicksort #stack-overflow
#java #быстрая сортировка #stack-overflow
Вопрос:
Могу ли я увеличить стек и кучу в java? Я использую BlueJ.
========
Редактировать:
Вот код:
// ***** Quick-Sort Method *****
public static void quickSort(int[] data, int first, int n)
{
int p, n1, n2;
if(n > 1)
{
p = partition(data, first, n);
n1 = p - first;
n2 = n - n1 - 1;
quickSort(data, first, n1);
quickSort(data, p 1, n2);
}
}
// ***** PRIVATE HELPER FUNCTIONS *****
public static void quickSort(int[] data)
{
quickSort(data, 0, data.length);
}
private static int partition(int[] A, int first, int n )
{
int right = first n - 1;
int ls = first;
int pivot = A[first];
for(int i = first 1; i <= right; i )
{
if(A[i] <= pivot)
// Move items smaller than pivot only, to location that would be at left of pivot
{
ls ;
swap(A, i, ls);
}
}
swap(A, first, ls);
return ls;
}
private static void swap(int[] data, int pos1, int pos2)
{
int temp = data[pos1];
data[pos1] = data[pos2];
data[pos2] = temp;
}
Комментарии:
1. вы уверены, что это не просто ошибка в вашем коде?
2. Я так не думаю, я заглянул в Google, и одна и та же проблема возникала много раз
3. @Eng: Если ваша быстрая сортировка не делит размер примерно на два на каждой итерации (что, бьюсь об заклад, это не так), с этим что-то не так. Дважды проверьте свой алгоритм. Готов поспорить, что ваш раздел просто каждый раз разбивает список на 1 элемент меньше.
4. Насколько велик набор данных, который вы пытаетесь выполнить быструю сортировку? Это почти отсортировано для начала? Вы написали свою собственную быструю сортировку? Увеличение размера стека без предварительного определения того, что на самом деле происходит, — действительно плохая идея.
5. Вероятно, у вас ошибка в вашем алгоритме, приводящая к бесконечной рекурсии, которая отображается как ошибка переполнения стека. Вставьте свой код, и мы сможем вам помочь.
Ответ №1:
Пытаться увеличить размер стека из-за переполнения было бы все равно, что покупать больше мусорных баков, когда ваш ящик заполнен, вместо того, чтобы отправлять его на свалку.
Скорее всего, вы переходите к бесконечной рекурсии. Не могли бы вы опубликовать свой код?
Комментарии:
1. Для коротких списков ваш код подходит. Для больших списков вам следует дерекурсифицировать свой алгоритм, таким образом избегая бомбардировки стека. Имейте в виду, что список, содержащий n элементов, вызовет до 2n-1 рекурсий.
2. На какой JavaVM вы его запускаете и какой длины ваш список. Список со 100000 элементами не является проблемой на моей виртуальной машине.
3. На моей виртуальной машине я могу сортировать списки с 10 миллионами участников без проблем. Вы работаете в особо стесненных условиях?
4. @div amp; @Hyperboreus Как я могу изменить свой JavaVM
5. Установив другой. Существуют различные реализации. Какой из них вы используете. Вызовите java -version и опубликуйте результат.
Ответ №2:
Вы можете использовать следующие параметры JVM:
-Xms
начальный размер кучи java-Xmx
максимальный размер кучи java-Xss
Установите размер стека потоков
Если вы хотите установить эти параметры по умолчанию в BlueJ, вам нужно сделать следующее:
- Найти
bluej.defs
файл - Найдите
bluej.vm.args
свойство (строку) в этом файле - Добавьте в эту строку нужный параметр, т.е.
bluej.vm.args = -Xmx512m
установить максимальный размер кучи в 512 МБ.
Я надеюсь, что это поможет.
Комментарии:
1. @bacchus Нет, как я могу это сделать?
2. Как я могу проверить размер моего стека?
3. Вы можете проверить трассировку стека и дополнительную информацию о памяти, используя JConsole, который устанавливается вместе с jdk.
4. @bacchus хм, как я могу увеличить размер стека в eclipse?
5. @Eng. Фуад Добавьте параметр, который вы хотите
eclipse.ini
сохранить.
Ответ №3:
Ошибка stackoverflow обычно возникает из-за неправильного рекурсивного вызова. Вы уверены, что не делаете ничего неправильного, например, указываете правильные пути выхода (они же условия завершения) для вашего потока рекурсии?
Ответ №4:
мне кажется, что это раздел, который прослушивается
private static int partition(int[] A, int first, int n )
{
int right = first n-1;
int ls = first;
int pivot = A[right];//use right most for pivot
for(int i = first;i<right;i )
{
if(A[i]<pivot){
swap(A,i,ls);
ls ;//inc after swap
}
}
swap(A,right,ls);
return ls;
}
Я получил этот код из википедии
Ответ №5:
Самая простая реализация быстрой сортировки уязвима для использования O (N) памяти в худшем случае. Можно изменить его, чтобы использовать O (log N) в наихудшем случае, выполнив рекурсию только в меньший подмассив и превратив оставшуюся рекурсию в цикл while:
//the following code probably contains of-by-one errors
quicksort(xs, begin, end):
while(not empty list){
mid = partition(xs, begin, end)
if( mid-begin < end-mid){
quicksort(xs, begin, mid)
end = mid
}else{
quicksort(xs, mid, end)
begin = mid
}