Как узнать наибольший номер элемента (размер массива), пусть сортировка вставкой превзойдет сортировку слиянием? - PullRequest
0 голосов
/ 30 ноября 2011

со страницы вики сортировки:

Некоторые алгоритмы «разделяй и властвуй», такие как быстрая сортировка и сортировка слиянием, рекурсивно делят список на меньшие подсписки, которые потом отсортировано. Полезная оптимизация на практике для этих алгоритмов использовать сортировку вставок для сортировки небольших подсписков, где сортировка вставок превосходит эти более сложные алгоритмы. Размер списка, для которого сортировка вставок имеет преимущество в зависимости от среды и реализации, но обычно от восьми до двадцати элементов.

цитата из вики имеет одну причину в том, что маленькие списки из сортировки слиянием не хуже для вставки сортировки.

Я хочу просто игнорировать эту причину.

Я знал, что если размер массива небольшой, то вставка сортировки O (n ^ 2) может превзойти Merge Sort O (n log n).

Я думаю (не уверен), что это связано с константами в T (n)

Вид вставки: T (n) = c1n ^ 2 + c2n + c3

Сортировка слиянием: T (n) = n log n + cn

теперь мой вопрос на том же компьютере, тот же случай (худший случай), как узнать наибольшее число элементов, пусть сортировка вставки побеждает сортировку слиянием?

Ответы [ 3 ]

1 голос
/ 30 ноября 2011

Все просто:

Возьмите набор выборочных массивов для сортировки и итерируйте по значению k, где k - точка отсечения при переходе от слияния к вставке.

тогда иди

for(int k = 1; k < MAX_TEST_VALUE; k++) {
    System.out.println("Results for k = " + k);
    for(int[] array : arraysToTest) {
        long then = System.currentTimeMillis();
        mergeSort(array,k); // pass in k to your merge sort so it uses that
        long now = System.currentTimeMillis();
        System.out.println(now - then);
    }
}

Что бы это ни стоило, класс java.util.Arrays может сказать об этом во внутренней документации:

/**
 * Tuning parameter: list size at or below which insertion sort will be
 * used in preference to mergesort or quicksort.
 */
private static final int INSERTIONSORT_THRESHOLD = 7;

/**
 * Src is the source array that starts at index 0
 * Dest is the (possibly larger) array destination with a possible offset
 * low is the index in dest to start sorting
 * high is the end index in dest to end sorting
 * off is the offset to generate corresponding low, high in src
 */
private static void mergeSort(Object[] src,
              Object[] dest,
              int low,
              int high,
              int off) {
    int length = high - low;

    // Insertion sort on smallest arrays
    if (length < INSERTIONSORT_THRESHOLD) {
        for (int i=low; i<high; i++)
            for (int j=i; j>low &&
         ((Comparable) dest[j-1]).compareTo(dest[j])>0; j--)
                swap(dest, j, j-1);
        return;
    }

В своих примитивных последовательностях он также использует 7, хотя и не использует постоянное значение.

0 голосов
/ 30 ноября 2011

Как правило, это делается путем тестирования с массивами различного размера. Когда n == 10, сортировка вставок почти наверняка быстрее. Когда n == 100, вероятно, нет. Тестируйте, тестируйте, тестируйте, пока ваши результаты не сойдутся.

Полагаю, возможно определить число строго путем анализа, но для этого вам нужно точно знать, какой код генерируется компилятором, включать время выполнения команд и учитывать стоимость кеша пропадает и т. д. Принимая во внимание все, самый простой способ - вывести его опытным путем.

0 голосов
/ 30 ноября 2011

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

Таким образом, вопрос «Как узнать наибольший номер элемента (размер массива), пусть сортировка вставкой превосходит сортировку слиянием?» Не совсем корректен.

редактировать: Просто чтобы получить внизу моей спины: Вопрос можно перефразировать как:

  1. "как определить наибольший размер массива, для которого в среднем сортировка вставки превосходит сортировку слиянием". Обычно это измеряется опытным путем путем создания выборки массивов небольшого размера и запуска реализаций обоих алгоритмов на них. Световой кодер делает это в своем ответе.
  2. «какой самый большой размер массива, для которого сортировка вставок в худшем случае работает лучше, чем сортировка слиянием» На это можно приблизительно ответить простым вычислением, поскольку IS должен делать n вставок и n * (n-1) перемещения элементов (которые являются вставками) в худшем случае, тогда как сортировка слиянием всегда делает n * logn копий ячеек из одного массива в другой. Так как это будет относительно небольшое количество, даже не имеет смысла рассматривать это.
...