Comments 55
Также стоило бы упомянуть такие сортировки как Boost.Sort и pdqsort, которая используется в Rust: они являются очень быстрыми.
А за бенчмарк спасибо — будет полезная ссылка.
Неплохая идея с https://github.com/Morwenn/cpp-sort/wiki/Fixed-size-sorters!
Методика и инструментарий у всех хромает на две ноги.
Что за системные глюки наблюдались?
Как измерялось время?
Имеет ли смысл сделать то же самое под Linux?
Пару раз за время тестирования система зависала на несколько минут, почему — не знаю.
Время измерялось встроенной в C++ функцией clock(), можете посмотреть в реализации.
Насчет Linux'а не знаю, у меня его нет.
Представим каждое число в двоичном видеА если в массиве не числа? Предлагаю изменить заголовок.
для точного и наилучшего используются другие обозначения Θ и Ω(ω)
см Введение в анализ сложности алгоритмов на хабре
std::make_heap(l, r);
std::sort_heap(l, r);
Построение кучи требует O(r-l) времени.Heapsort требует O(1) дополнительной памяти.
pastebin.com/BRRHx0pd
Ваш вариант — 2.29, STL-вариант — 2.08
Надеюсь, Вы выбрали конфигурацию Release x64 в MSVC.
ideone.com/FdmsOw
Рекомендую почитать про двоичную кучу тут: neerc.ifmo.ru/wiki/index.php?title=%D0%94%D0%B2%D0%BE%D0%B8%D1%87%D0%BD%D0%B0%D1%8F_%D0%BA%D1%83%D1%87%D0%B0
В особенности раздел Построение кучи за O(n)
Во-первых, мне кажется, для одной статьи это слишком большое число алгоритмов. Было бы лучше сгруппировать их в 2-3 группы. Например, по устойчивости (сохранении порядка элементов с одинаковым значением ключа) или по другому критерию.
Во-вторых, не хватает сводной таблички, в которой бы указывались такие характеристики:
1. Устойчивость — сохраняется ли порядок элементов с одинаковыми значениями ключей.
2. Естественность — сортируется ли уже упорядоченный массив быстрее, чем случайный, а случайный быстрее, чем упорядоченный в обратном порядке.
3. Производительность в лучшем, среднем, худшем случаях.
4. Требования к дополнительной памяти (и ее порядок).
5. Области применения (например, для сортировок малых почти упорядоченных массивов и др.).
И еще… Могу, конечно, путать, но, как мне кажется, сортировка слиянием существует в двух вариантах — с дополнительной памятью размера O(n) и без дополнительной памяти — т.е. размера O(1).
И производительность этих сортировок весьма различается.
У этого алгоритма известны 2 практические реализации:
GrailSort (на гитхабе) покойного Mrrl
- WikiSort
Оба этих алгоритма включены в cpp-sort
Что имеется в виду под «затем отсортировать по двум ключам»? Выполнить сортировку в два этапа?
Если делать второй этап только по втолрому ключу, то получим неотсортированный исходный массив.
Если делать второй этап по составному ключу, то смысла в нем нет — можно сразу первым этапом отсортировать по этому составному ключу. Тогда, действительно, получим сохранившийся порядок элементов с одинаковыми первыми ключами.
Только вот к устойчивости алгоритма это не будет иметь абсолютно никакого отношения. Тому как составной ключ будет уникальным. А устойчивость проявляется именно для массивов данных с неуникальными ключами. Причем, проявляется как естественная характеристика алгоритма, не требующая дополнительных телодвижений в виде введения вторичных/составных ключей или сортировки в несколько этапов по этим искусственно введенным ключам.
Я имел в виду алгоритм Пратта слияния двух предварительно отсортированных частей массива «на месте»: ru.wikipedia.org/wiki/Устойчивая_сортировка
Так что, сведения о том, что там перечислены «все сортировки во всех возможных модификациях, доступных человеческому разуму, возможно, актуальные до момента тепловой смерти нашей Вселенной» несколько преувеличены :)
Сортировки расческой там нет. Хотя идея ее проста и просто сама напрашивается. Сам писал программы по похожему алгоритму лет 30 назад, но не такие эффективные, потому что набор дистанций брал каким угодно (числа Фиббоначи, степени двойки — 1, последовательные простые числа и т.д.), а про снижающий коэффициент 1,247331… только сейчас прочитал.
А ведь в этом коэффициенте как раз весь смысл этого алгоритма.
Мне к примеру, надо быстро сортировать 20и битовые данные и их 100 000 000.
Я раньше считал, что самый подходящий способ делёж файла на 30 частей и — Merge Sort.
Сейчас вижу есть другие варианты…
Ну а всё же — что наиболее подходит?
СУБД умеют собирать статистику, но у них, насколько я в курсе, ограниченный набор алгоритмов, и это не сортировка, а хранение: хеш/дерево/битмап…
Устаревшая основа статьи.
Академические источники какие?
https://github.com/scandum/quadsort
https://github.com/PatwinchIR/ultra-sort
На днях смог таки свою сортировку реализовать, за пару дней сделал на ассемблере. Работает со строками, именно под строки заточена, как называется точно по научному, не могу назвать, но типа поразрядная, ну по байтам. Работает быстро, файл leipzig1M.txt весом 123 МБ и 1000000 строк, от сортировала за ~0.8 сек. Трудно с чём то сравнить, но это довольно быстро, быстрей быстрой сортировки должно быть, но пока соревнований не делал. Алгоритм придумал очень давно, когда у меня и компьютера то не было. Алгоритм конечно довольно простой, да у всех простой, сотня кода максимум. А, ПК Ryzen 5 3600X 3.79 GHz достаточно быстрый, но не самый.
Судя по размеру файла, его сортировка производится полностью в памяти.
А как быть, если в память он не помещается и приходится сортировать по частям, а потом их сливать? В этом случае кроме быстрой сортировки в памяти хотелось бы иметь оптимизацию операций с файлами. Хотя бы уменьшение числа операций чтений/записи.
Передаю привет Картановой А.Д.
Описание алгоритмов сортировки и сравнение их производительности