2015-04-27 7 views
3

Я сделал кучу попыток алгоритма быстрой сортировки, который я просто не могу заставить работать. Этот код является самым близким я получил, за исключением того, что он примерно один раз в пять раз не полностью сортирует - он выводит что-то вроде 266, 186, 219, 276, 357, 405, 686, 767, 834, 862. Я попытался найти общность между всеми наборами чисел, которые делают это, но я ничего не могу найти. Я провел много часов, пробираясь через него с помощью отладчика, но ничего не вижу (хотя я чувствую, что мне не хватает чего-то очевидного). Что я делаю не так?Quicksort иногда не заканчивается?

public static void sort(ArrayList<Integer> arr, int left, int right) { 
    int i = left - 1, j = right, v = arr.get(right); 
    if(right - i == 0 || right - i == 1)return; 

    for(;;) { 
     while(arr.get(++i) < v); 
     while(v < arr.get(--j) && j != 0) 
      if(j == 1)break; 
     if(i >= j)break; 

     Collections.swap(arr, i, j); 
    } 
    Collections.swap(arr, i, right); 

    sort(arr, left, i - 1); 
    sort(arr, i, right); 
} 
+0

Ваш первый номер - это то, что не сортируется, так что вот где я начну выглядеть –

+1

Проследите его по бумаге шаг за шагом. Запишите на каждом шаге значение каждой переменной и массив. Не записывайте то, что, по вашему мнению, должно быть, запишите, что на самом деле говорят инструкции. Когда вы прослеживаете это таким образом, вы получаете гораздо лучшее понимание вещей. – kojow7

+0

Пойду, сделаю это сейчас, спасибо. Я откладывал это делать до сих пор из-за того, сколько итераций он проходит (что означает сотни строк на бумаге). – IHazABone

ответ

2

Я сделал две вещи, чтобы ваш код, чтобы заставить его работать:

в начале метода установить j = right +1 и двигаться v = arr.get(right) к после первой, если заявление.

должен выглядеть примерно так:

public static void sort(ArrayList<Integer> arr, int left, int right) { 
     int i = left - 1; 
     int j = right + 1; 
     if (right - i == 0 || right - i == 1) return; 
     int v = arr.get(right); 

     for (;;) { 
      while (arr.get(++i) < v); 
      while (v < arr.get(--j) && j != 0) 
       if (j == 1) break; 
      if (i >= j) break; 

      Collections.swap(arr, i, j); 
     } 
     Collections.swap(arr, i, right); 

     sort(arr, left, i - 1); 
     sort(arr, i, right); 
    } 

Но это было действительно нечитаемым код, вы должны прочитать книгу CleanCode.

+0

Я попробую в следующий раз получить шанс, но что касается моего кода, который «действительно нечитабелен», все, что вы делали, было отдельным объявлением переменной вверху. – IHazABone

+0

И почему List вместо ArrayList? – IHazABone

+0

Измененный список обратно в ArrayList сделал это, чтобы написать единичный тест без моей IDE, кричащей тонны предупреждений. – osundblad

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