Эффективный алгоритм сортировки для почти отсортированного списка, содержащего данные времени?

имя говорит все это на самом деле. Я подозреваю, что сортировка вставки лучше всего, так как это лучшая сортировка для в основном отсортированных данных в целом. Однако, поскольку я знаю больше о данных, есть шанс, что есть другие виды, которые смотрят. Таким образом, другие соответствующие части информации:

1) это данные времени, что означает, что я предположительно мог бы создать эффективный хэш для упорядочения данных. 2) данные не будут существовать одновременно. вместо этого я буду читать записи, которые могут содержат один вектор, или дюжину, или сотни векторов. Я хочу выводить все время в 5 секунд. Поэтому возможно, что сортировка, которая выполняет сортировку при вставке данных, будет лучшим вариантом. 3) память не является большой проблемой, но скорость процессора, как это может быть узким местом системы.

учитывая эти условия, может ли кто-нибудь предложить алгоритм, который стоит рассмотреть в дополнение к сортировке вставки? Кроме того, как определить "в основном отсортированы", чтобы решить, что такое хороший вариант сортировки? Я имею в виду, как я смотрю на свои данные и решил: "это не так Отсортировано, как я думал, возможно, сортировка вставки больше не лучший вариант"? Любая ссылка на статью, в которой рассматривается сложность процесса, которая лучше определяет сложность относительно степени сортировки данных, будет оценена.

спасибо

изменить: спасибо всем за информацию. Я буду идти с легкой вставкой или сортировкой слияния (в зависимости от того, что у меня уже есть pre-written) на данный момент. Однако я попробую некоторые другие методы, которые когда-то были ближе к фазе оптимизации (поскольку они требуют больше усилий для реализации). Я ценю помощь

6 ответов


вы можете принять вариант (2), который вы предложили - сортировать данные во время вставки элементов.

использовать пропустить, сортируется по времени, по возрастанию для поддержания ваших данных.

  • как только новый entree прибывает-проверьте, если он больше, то последний элемент (легко и быстро) если это - просто добавьте его (легко сделать в списке пропусков). Этот список пропусков нужно будет добавить 2 узла в среднем для этих случаев, и будет O(1) на средний для этих случаи.
  • если элемент не больше, то последний элемент-добавьте его в пропустить список как стандартную вставку op, которая будет O(logn).

этот подход даст вам , где k - количество элементов, вставленных в порядке.


Я бы бросил в сортировка слиянием если вы реализуете естественную версию, вы получите лучший случай O(N) с типичным и худшим случаем O(N log N) если у вас есть какие-либо проблемы. Вставка вы получаете худший случай O(N^2) и лучший случай O(N).


вы можете сортировать список размеров n с k элементы в O(n + k lg k) времени.

см.: http://www.quora.com/How-can-I-quickly-sort-an-array-of-elements-that-is-already-sorted-except-for-a-small-number-of-elements-say-up-to-1-4-of-the-total-whose-positions-are-known/answer/Mark-Gordon-6?share=1

основная идея такова:

  • итерация по элементам массива, построение возрастающего подпоследовательность (если текущий элемент больше или равен последнему элементу подпоследовательности, добавьте его в конец подпоследовательности. В противном случае отбросьте как текущий элемент, так и последний элемент подпоследовательности). Это занимает O(n) времени.
  • вы отбросите не более чем 2k элементы, начиная с k элементы неуместны.
  • Сортировать 2k элементы, которые были удалены с помощью O(k lg k) алгоритм сортировки, как сортировка слиянием или пирамидальная сортировка.
  • теперь у вас есть два отсортированных списков. Объедините списки в O(n) время, как вы бы на шаге слияния сортировки слияния.

общая сложность времени = O(n + k lg k)

общая сложность пространства = O(n)

(это может быть изменено для запуска в O(1) пространство, если вы можете слиться в O(1) пространство, но это отнюдь не тривиально)


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


существует много адаптивных алгоритмов сортировки, которые специально разработаны для сортировки в основном отсортированных данных. Игнорируя тот факт, что вы храните даты, вы можете посмотреть на smoothsort или декартова сортировка дерева как алгоритмы, которые могут сортировать данные, которые разумно отсортированы в худшем случае O(N log n) время и в лучшем случае O (n) время. Smoothsort также имеет преимущество, требуя только O (1) пространство, как вставка сортировки.

используя тот факт, что все является дата и, следовательно, может быть преобразована в целое число, вы можете посмотреть на binary quicksort (MSD radix sort), используя выбор медианы из трех пивотов. Этот алгоритм имеет наилучшую производительность O(N log n), но имеет очень низкий постоянный коэффициент, что делает его довольно конкурентоспособным. Его худший случай-O (N log U), где U-количество бит в каждой дате (возможно, 64), что не так уж плохо.

надеюсь, что это помогает!


Если ваша библиотека OS или C предоставляет функцию mergesort, очень вероятно, что она уже обрабатывает случай, когда данные частично упорядочены (в любом направлении), работающие в O(N) времени.

в противном случае вы можете просто скопировать mergesort, доступный из вашей любимой операционной системы BSD.