Вы можете отсортировать n чисел за o(n) по амортизированной сложности?

теоретически возможно ли отсортировать массив из n целых чисел в амортизированной сложности O (n)?

Как насчет попытки создать худший случай сложности O(n)?

большинство алгоритмов сегодня построены на среднем O(nlogn) + o(n^2) худшем случае. Некоторые, при использовании большего объема памяти, являются o (nlogn) худшими.

можно без ограничений на использование памяти создать такой алгоритм? Что если ваша память ограничена? как это повредит вашему алгоритму?

4 ответов


любая страница в intertubes, которая имеет дело с сортировками на основе сравнения скажу вам что ты не может сортировать быстрее, чем O(n lg n) при сравнении сортов. То есть, если ваш алгоритм сортировки решает порядок, сравнивая 2 элемента друг с другом, вы не можете сделать лучше. Примеры включают quicksort, bubblesort, mergesort.

некоторые алгоритмы, такие как count sort или bucket sort или radix sort, не используют сравнения. Вместо этого, они полагаются на свойства самих данных, такие как диапазон значений в данных или размер значения данных.

эти алгоритмы может имеют более быстрые сложности. Вот пример сценария:

вы сортируете 10^6 целые числа, и каждое целое число находится между 0 и 10. Затем вы можете просто подсчитать количество нулей, единиц, двоек и т. д. и выплюнуть их обратно в определенном порядке. Вот как работает countsort, в O(n + m) здесь m is количество значений, которые может принимать ваш datum (в этом случае m=11).

другое:

вы сортируете 10^6 двоичные строки, которые не более 5 символов в длину. Для этого вы можете использовать сортировку radix: сначала разбейте их на 2 ведра в зависимости от их первого символа, затем radix-сортируйте их для второго символа, третьего, четвертого и пятого. Пока каждый шаг является стабильным, вы должны получить идеально отсортированный список в O(nm), где m-количество цифр или битов в вашем датуме (в этом случае m=5).

но в общем случае вы не можете сортировать быстрее, чем O(n lg n) надежно (используя сортировку сравнения).


Я не совсем доволен принятым ответа до сих пор. Поэтому я повторяю ответ:

теоретически возможно ли отсортировать массив из n целых чисел в амортизированной сложности O (n)?

ответ на этот вопрос зависит от машины, которая будет выполнять алгоритм сортировки. Если у вас есть машина произвольного доступа, которая может работать ровно на 1 бит, вы можете сделать radix sort для целых чисел с не более k биты, что уже предлагалось. Таким образом, вы в конечном итоге со сложностью O(kn).
Но если вы работаете на машине слов фиксированного размера с размером слова не менее k биты (которые все потребительские компьютеры), лучшее, что вы можете достичь, это O(n log n). Это потому, что либо log n < k или графа вроде сначала, а затем сортировать с O (n log n) алгоритм, который также даст первый случай.

как насчет попытки создать наихудший случай O(n) сложность?

это невозможно. Ссылка уже была дана. Идея доказательства заключается в том, что для того, чтобы иметь возможность сортировать, вы должны решить для каждого элемента, который будет отсортирован, если он больше или меньше любого другого элемента для сортировки. Используя транзитивность, это можно представить как дерево решений, которое имеет n узлы и log n глубина в лучшем случае. Поэтому, если вы хотите иметь производительность лучше, чем Ω(n log n) это означает удаление ребра из этого дерева решений. Но если дерево решений не является полным, чем как вы можете убедиться, что вы сделали правильное решение о некоторых элементах a и b?

можно без ограничений на использование памяти создать такой алгоритм?

так как сверху это невозможно. Поэтому остальные вопросы не имеют значения.


Если целые числа находятся в ограниченном диапазоне, то O (n) "сортировка" из них будет включать наличие битового вектора "n" бит ... цикл над целыми числами в вопросе и установка N%8 бит смещения n//8 в этом массиве байтов в true. Это операция" O(n)". Другой цикл над этим битовым массивом для перечисления / перечисления / возврата / печати всех заданных битов также является операцией O(n). (Естественно, O (2n) сводится к O(n)).

Это особый случай, когда n достаточно мал, чтобы поместиться внутри память или в файле (с операциями seek ()). Это не общее решение; но оно описано в "жемчужинах программирования" Бентли-и, как утверждается, было практическим решением проблемы реального мира (с участием чего-то вроде "фрилиста" телефонных номеров ... что-то вроде: найти первый доступный номер телефона, который может быть выдан новому абоненту).

(Примечание: log (10*10) составляет ~24 бита для представления каждого возможного целого числа длиной до 10 цифр ... так много комната в 2*31 бит типичного отображения памяти максимального размера Unix/Linux).


Я считаю, что вы ищете сортировка radix.