2013-12-13 5 views
0

я реализовал быструю сортировку массива целых чисел следующим образом:Quicksort переполнения стека

public void Quicksort(int left, int right) 
{ 
    /* The recursive quicksort algorithm consists of four steps: 
    * 1. If there are one or less elements in the array to be sorted, return immediately. 
    * 2. Pick an element in the array to serve as a "pivot" point. (Usually the left-most element in the array is used.) 
    * 3. Split the array into two parts - one with elements larger than the pivot and the other with elements smaller than the pivot. 
    * 4. Recursively repeat the algorithm for both halves of the original array. 
    */ 

    int pivot = dataTable[left]; 

    int l_hold = left; 
    int r_hold = right; 

    while (left < right) 
    { 
     while ((dataTable[right] >= pivot) && (left < right)) 
      right--; 

     if (left != right) 
     { 
      dataTable[left] = dataTable[right]; 
      left++; 
     } 

     while ((dataTable[left] <= pivot) && (left < right)) 
      left++; 

     if (left != right) 
     { 
      dataTable[right] = dataTable[left]; 
      right--; 
     } 
    } 

    dataTable[left] = pivot; 
    pivot = left; 
    left = l_hold; 
    right = r_hold; 

    if (left < pivot) 
     Quicksort(left, pivot - 1); 

    if (right > pivot) 
     Quicksort(pivot + 1, right); 
} 

Она работает нормально с массивом, скажем, 500 000 случайным образом сгенерированных чисел. Если я заполняю массив с восходящими или нисходящими целыми числами, quicksort вызывает исключение StackOverflowException около 8800 элементов.

Я шпионирую своим маленьким глазом, не имея ясной причины для этого. Можете ли вы подсмотреть за своими огромными количествами глаз? Я мог бы пойти и просто найти copypasta функционала quicksort, но я бы скорее нашел причину относительно того, что вызывает проблему.

Метод работает с массивом, который является частью класса и обычно вызывается с (индекс 0, последний индекс - 1). Тысячи благодарностей!

+2

Вы слишком глубоко рекурсивы. У вас есть только около 1 Мб пространства стека для работы, и после его использования вы получите эту ошибку. Случайный массив, вероятно, перестает рекурсировать довольно быстро, потому что он достигнет равного числа. Восходящий/нисходящий будет делать всю глубину значений каждый раз из-за того, как вы его настроили. Это означает, что вы регенерируете глубину . – steveg89

+0

Возможно, вы захотите рассмотреть, чтобы перейти от рекурсивного дизайна к итеративному. Я бы предложил проверить эту тему: http://stackoverflow.com/questions/159590/way-to-go-from-recursion-to-iteration – MrPaulch

ответ

0

Вы испытываете рекурсию хвоста. Проще говоря, компилятор C# не очень хорошо справляется с этим. Я читал, что если у вас есть проблемы с этим при отладке, вы можете попробовать скомпилировать в режиме выпуска с оптимизацией, и это облегчит проблему.

Существует способ более подробной информации here.

0

Необходимо добавить условие остановки.

function() { 

if(value == 0) { 
break; 
} else { 
function()) 
} 

Вы не можете звонить в Quicksort все время. Для этого требуется условие остановки/разрыва.

Смежные вопросы