Почему Bubble сортировка работает лучше, чем сортировка Selection в среднем случае - PullRequest
4 голосов
/ 17 апреля 2020

Я использую алгоритмы сортировки маркировки, используя java. Когда я сравниваю среднюю сортировку Bubble с сортировкой Selection, используя рандомизированные массивы в диапазоне от 0 до 99, сортировка Bubble работает заметно лучше. В большинстве ссылок на производительность, которые я прочитал, указано, что сортировка по разделам является лучшей из двух.

Selection vs Bubble vs Insertion

Это моя реализация Selection:

public static void selectionSort(int[] arr) {
        /*
         * Selection sort sorting algorithm. Cycle: The minimum element form the
         * unsorted sub-array on he right is picked and moved to the sorted sub-array on
         * the left.
         * 
         * The outer loop runs n-1 times. Inner loop n/2 on average. this results in
         * (?−1)×?2≈?2 best, worst and average cases.
         * 
         */

        // Count outer
        for (int i = 0; i < arr.length; i++) {
            // Assign the default min index
            int min = i;
            // Find the index with smallest value
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[j] < arr[min]) {
                    min = j;
                }
            }
            // Swap index arr[min] with a[i]
            int temp = arr[min];
            arr[min] = arr[i];
            arr[i] = temp;
        }
    }

Моя сортировка по пузырькам:

public static void optimalBubbleSort(int[] arr) {
          /**
           * The optimized version will check whether the list
           * is sorted at each iteration. If the list is sorted the 
           * program will exist.
           * Thus the best case for the optimized bubble sort 
           * is O{n). Conversely the above algorithm
           * the best case will always be the same as the average case.
           * 
           */
        boolean sorted = false;
        int n = arr.length;
        while (!sorted) {
          sorted = true;
          for (int i = 0; i < n - 1; i++) {
            if (arr[i] > arr[i + 1]) {
              int temp = arr[i + 1];
              arr[i + 1] = arr[i];
              arr[i] = temp;
              sorted = false;
            }
          }
          n--;
        }
      }

Моя реализация сортировки по пузырькам не оптимизирована для выхода при сортировке списка:

for (int i = 0; i < arr.length - 1; i++) {
          /*
           * Iteration of the outer loop will ensure
           * that at the end the largest element is in the 
           * (array.lenght-(i+1))th index.
           * Thus the loop invariant is that 

           * In other words, the loop invariant is that
           * the subsection bounded by the indices
           * [arr.length - i, arr.length] is sorted and
           * contains the i biggest elements in array.
           */

          for (int j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
              /*
               * In the case where an inversion exists in 
               * arr[j] > arr[j + 1],
               * arr[j] and arr[j + 1] are
               * thus swapped.
               */
              int temp = arr[j + 1];
              arr[j + 1] = arr[j];
              arr[j] = temp;
            }
          }
        }

Так я генерирую рандомизированный массив для inout :

int[] random = new int[n];
        for (int i = 0; i < n; i++) {
            random[i] = randomInteger.nextInt(100);
        }

Любая информация о том, почему Bubble сортируется быстрее.

Ответы [ 3 ]

1 голос
/ 17 апреля 2020

Если я прав, вы сортируете значения в диапазоне [0, 99] и массивы длиной до 100000. Это означает, что каждое значение может повторяться в среднем до 1000 раз.

IMO yo вы можете отбросить все свои результаты s, когда вы тестируете очень особые случаи, когда большое количество ключей совпадает и алгоритмы могут вести себя нестандартно. Их производительность будет более чувствительной к обычно незначительным деталям реализации. Классические алгоритмы сортировки не были разработаны для таких экстремальных ситуаций.

Я хотел бы добавить, что сравнение медленных сортировок с быстрыми сортировками на больших наборах данных не имеет большого смысла (кривые для быстрых сортировок настолько плотно упакованы что вы не можете сравнить ни один из них.)

1 голос
/ 17 апреля 2020

Таким образом, если мы сравним количество сравнений, оба алгоритма будут иметь что-то около n*(n+1)/2 (или просто сумму всех чисел от n до 1), что примерно равно n^2, как вы указали.

У сортировки выбора, безусловно, меньше свопов, чем у пузырьковой, но дело в том, что она будет go по всему массиву и сортируется, даже если она уже отсортирована. При сортировке массива пузырьковая сортировка фактически будет делать около n сравнений, что в лучшем случае будет иметь O(n) сложность по времени. Это также будет быстрее, когда массив будет почти отсортирован, что в среднем приводит к тому, что пузырьковая сортировка будет быстрее, чем сортировка вставкой. Вы можете найти большую букву О каждого случая на этом сайте

И на этом сайте вы можете увидеть, что на самом деле происходит, если массив уже или почти отсортирован.

0 голосов
/ 17 апреля 2020

Как вы обнаружили, основное различие между пузырьковой сортировкой и сортировкой выбора заключается в том, что пузырьковая сортировка может работать намного быстрее, чем сортировка выбора, когда массив (почти) отсортирован. В вашем случае, когда вы выбираете случайное число между 0 и 100, если выбранная длина массива n намного меньше 100, вероятность (почти) отсортированной выборки будет увеличена. В этом смысле вы можете обнаружить, что средняя сложность сортировки пузырьков лучше, чем сортировка выбора.

Таким образом, вы должны знать, что это сравнение зависит от n, и если вы увеличите значение n, так как вероятность отсортированных массивов уменьшится, вы найдете эти две кривые ближе.

...