Использование красных черных деревьев для сортировки

В худшем случае время вставки в red-black tree равно O(lg n), и если я выполняю in-order walk в дереве, я по существу посещаю каждый node, поэтому общее время выполнения в худшем случае для печати сортированная коллекция будет O (n lg n)

Мне любопытно, почему red-black trees не является предпочтительным для сортировки по quick sort (чей средний период работы O(n lg n).

Я вижу, что, возможно, потому, что red-black trees не сортируется на месте, но я не уверен, возможно, кто-то может помочь.

Ответы

Ответ 1

Знание того, какой алгоритм сортировки лучше работает, действительно зависит от ваших данных и ситуации.

Если вы говорите в общем/практическом плане,

Quicksort (тот, где вы выбираете шарнир случайно или просто выбираете один фиксированный, делая наихудший случай Omega (n ^ 2)), может быть лучше, чем красно-черные деревья, потому что (не обязательно в порядке важности)

  • Quicksort на месте. Сохраняет низкий уровень памяти. Скажем, эта процедура quicksort была частью программы, которая занимается большим количеством данных. Если вы продолжаете использовать большие объемы памяти, ваша ОС может начать замену вашей памяти процесса и уничтожить ваш перформанс.

  • Доступ к быстрой сортировке памяти локализован. Это хорошо работает с кэшированием/заменой.

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

  • Если бы вы попытались оптимизировать сортировку двоичного дерева (используя двоичное дерево без балансировки), используя вместо этого массив, вы в конечном итоге сделаете что-то вроде Quicksort!

  • Красно-черные деревья имеют накладные расходы памяти. Вы должны распределять узлы, возможно, несколько раз, ваши требования к памяти с деревьями удваиваются/трижды, используя массивы.

  • После сортировки, скажем, вам нужен элемент 1045 (скажем), вам нужно будет поддерживать статистику заказа в своем дереве (из-за этого требуется дополнительная стоимость памяти), и у вас будет время доступа O (logn)!

  • Красно-черные деревья имеют накладные расходы только для доступа к следующему элементу (поиск указателей)

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

  • Вращение в красно-черных деревьях увеличит постоянный коэффициент в O (nlogn).

  • Возможно, самая важная причина (но не действительна, если у вас есть lib и т.д.), Quicksort очень прост для понимания и реализации. Даже школьный ребенок может это понять!

Я бы сказал, что вы пытаетесь измерить обе реализации и посмотреть, что произойдет!

Кроме того, Боб Седжуик сделал тезис о быстрой сортировке! Возможно, стоит прочитать.

Ответ 2

Существует множество алгоритмов сортировки, которые в худшем случае O(n log n) - например, merge sort. Причина, по которой quicksort предпочтительнее, заключается в том, что она на практике быстрее, хотя алгоритмически она может быть не так хороша, как некоторые другие алгоритмы.

Часто встроенные сортировки используют комбинацию различных методов в зависимости от значений n.

Ответ 3

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

Деревья лучше для Dups:  Все тесты, в которых необходимо дублировать дублирование, алгоритм дерева лучше. Это не удивительно, так как дерево можно сохранить очень мало с самого начала, в результате чего алгоритмы, предназначенные для сортировки массива inline, могут проходить более крупные сегменты в течение более длительного времени.

Деревья лучше для Random: Все тесты со случайным алгоритмом дерева лучше. Это также не удивительно, так как на дереве расстояние между элементами короче и смещение не требуется. Поэтому многократная вставка в дерево может потребовать меньше усилий, чем сортировка массива.

Итак, создается впечатление, что естественное слияние происходит только в возрастающих и нисходящих особых случаях. Которую нельзя сказать даже для быстрого сортировки.

Gist с тестовыми примерами здесь.

P.S.: следует отметить, что использование деревьев для сортировки является нетривиальным. Нужно не только предоставить процедуру вставки, но и процедуру, которая может линеаризовать дерево обратно в массив. В настоящее время мы используем процедуру get_last и predecessor, которая не нуждается в стеке. Но эти подпрограммы не O (1), поскольку они содержат циклы.

Ответ 4

В измерениях сложности времени Big-O обычно не учитываются скалярные факторы, например, O (2n) и O (4n) обычно просто сводятся к O (n). Анализ временной сложности основан на операционных шагах на алгоритмическом уровне, а не на строгом уровне программирования, то есть нет исходных кодов или соображений собственной машинной инструкции.

Quicksort обычно быстрее, чем сортировка на основе дерева, поскольку (1) методы имеют одинаковую среднюю временную сложность алгоритма, и (2) операции поиска и свопинга требуют меньше программных команд и доступа к данным при работе с простыми массивами, черные деревья, даже если дерево использует базовую реализацию на основе массива. Для поддержания ограничений красного-черного дерева требуются дополнительные рабочие шаги, хранение/доступ к значениям поля данных (цвета node) и т.д., Чем простые шаги обмена секциями массива быстрой сортировки.

Конечным результатом является то, что красно-черные деревья имеют более высокие скалярные коэффициенты, чем quicksort, которые затушевываются стандартным результатом анализа временной сложности O (n log n).

Некоторые другие практические соображения, связанные с машинной архитектурой, кратко обсуждаются в статье Quicksort в Википедии

Ответ 5

В общем случае представления алгоритмов O (nlgn) можно разложить на A * nlgn + B, где A и B - константы. Существует много алгоритмических доказательств, которые показывают, что коэффициенты для quicksort меньше, чем у других алгоритмов. Это в лучшем случае (быстрая сортировка выполняется ужасно на отсортированных данных).

Ответ 6

Привет, лучший способ объяснить разницу между всеми процедурами сортировки, на мой взгляд. (Мой ответ для людей, которые запутываются, как быстро сортировка на практике быстрее, чем другой сортирующий алгоритм).

"Думаю, вы работаете на очень медленном компьютере".

  • Первое, что требуется для сравнения, занимает 1 час.
  • Одна операция переключения занимает 2 часа.

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

Теперь из всех сортировочных операций quick-sort имеет очень малое сравнение и очень мало заменяет элементы.

Быстрая сортировка выполняется быстрее по этой основной причине.