it-swarm.com.ru

Каков наилучший алгоритм сортировки массива маленьких целых чисел?

Согласно заголовку вопроса, если массив имеет нечетную длину и элементы массива пронумерованы от 1 до 10.

Пример,

3 6 8 1 3 7 7 9 4 1

Я думал об использовании heapsort? Поскольку это массив, сортировка слиянием и сортировка вставкой требует сдвига и не будет столь эффективной.

18
user236501

элементы массива имеют номера от 1 до 10.

С этим ограничением считая сортировку будет намного эффективнее, чем любой алгоритм сортировки общего назначения - это O (n)

31
Michael Borgwardt

Это мой пример сортировки

static int[] countingSort(int[] numbers) {
    int max = numbers[0];
    for (int i = 1; i < numbers.length; i++) {
        if (numbers[i] > max)
            max = numbers[i];
    }

    int[] sortedNumbers = new int[max+1];

    for (int i = 0; i < numbers.length; i++) {
        sortedNumbers[numbers[i]]++;
    }

    int insertPosition = 0;

    for (int i = 0; i <= max; i++) {
            for (int j = 0; j < sortedNumbers[i]; j++) {
                    numbers[insertPosition] = i;
                    insertPosition++;
            }
    }
    return numbers;
}
7
ben_muc

Правка: сортировка подсчета, вероятно, является оптимальным, учитывая ограничение, что элементы только в диапазоне 1-10. Счетная сортировка, примененная к этой проблеме, будет запущена через O(n) время. Сортировка слиянием (как я рекомендовал ниже) будет выполняться не лучше, чем O(nlogn) время. Распараллеливание подсчета может быть интересным. Просто назначьте подрешетку с элементами n/p каждому процессору. Каждый процессор будет иметь свой собственный массив счетчиков размером 9. Этот шаг должен занять O(n/p) время. Затем объедините все массивы count в один массив, что должно занять O(p) время. Я не до конца продумал последний этап сортировки подсчета, где элементы располагаются по порядку, но кажется, что если элементы массива count являются атомарными, вы можете назначить n/p разделы исходного массива отдельным процессоры и добиться некоторого распараллеливания. Однако в отдельных элементах массива count может возникнуть конфликт, что может существенно снизить параллелизм. Возможно, вы сможете назначить подразделы массива count для p процессоров, и вы вернетесь к O(n/p) среде выполнения, если элементы распределены довольно равномерно, но вы будете ограничены 10 процессорами. Если элементы не распределены равномерно, один или несколько процессоров могут выполнять большую часть работы. Это отличный вопрос; Можете ли вы сделать сортировку подсчета во время O(n/p)?

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

Если вы не заботитесь о памяти, простой Mergesort будет достаточно. Mergesort предлагает самые быстрые стандартные алгоритмы сортировки.

Реализация Collections.sort () по умолчанию в Java 7 представляет собой алгоритм Mergesort, адаптированный из TimSort. Реализация Arrays.sort () по умолчанию в Java 7 представляет собой двойную сводную сортировку.

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

2
broadbear

Если есть только 10 элементов, не стоит даже беспокоиться об этом. Если их миллион, это может стать значительным.

2
user207421

Вы должны рассмотреть это для диаграммы сложности Сравнительная таблица сложности .

Сравнение алгоритма сортировки основано на сценарии "Лучший, средний, наихудший случай" для сложности времени и пространства. На этой диаграмме вы можете увидеть, что счетная сортировка подход лучше всего подходит как для пространственной, так и для временной сложности. Другим сопоставимым методом является Radix Sort.

Наихудшая [Time, Space] сложность "Подсчет сортировки": - [O (n + k), O (k)].

Худшая [Time, Space] сложность "Сортировки по радиксу": - [O (nk), O (n + k)].

1
bibek koirala

QuickSort - это алгоритм "разделяй и властвуй". Он выбирает элемент как pivot и разделяет данный массив вокруг выбранной pivot, а затем повторяет процесс. Есть много разных версий быстрой сортировки, которые выбирают сводку по-разному.

1
sdfahklj

Подсчет сортировки будет лучшим в этом сценарии.

Предполагая, что данные являются целыми числами, в диапазоне 0-k. Создайте массив размера K, чтобы отслеживать количество отображаемых элементов (3 элемента со значением 0, 4 элемента со значением 1 и т.д.). Учитывая это количество, вы можете определить положение элемента - все 1 должны следовать за 0, из которых 3. Поэтому 1 начинается с элемента № 4. Таким образом, мы можем сканировать элементы и вставлять их в правильное положение.

Создание массива счетчиков - это O(N) Вставка элементов в их правильное положение - это O(N) Здесь я упрощен - здесь есть сумма значений и наибольшее значение для наименьший порядок, который сохраняет стабильность.

0
Sai prateek

это пример простой сортировки (вставка сортировки)

private static void insertionSort(int[] a) {

    // [230, 23, 45, 34, 98]
    for (int j = 2; j < a.length; j++) {

        int key = a[j];
        int i = j - 1;

        while (i > 0 && a[i] > key) {
            a[i + 1] = a[i];
            i--;
        }
        a[i + 1] = key;
    }

    System.out.println("sorted array: " + Arrays.toString(a));
}
0
Yousuf Qureshi