Для ЯПматематиков пост: визуализация работы 19 алгоритмов сортировки

[ Версия для печати ]
Добавить в Telegram Добавить в Twitter Добавить в Вконтакте Добавить в Одноклассники
Страницы: (3) [1] 2 3   К последнему непрочитанному [ ОТВЕТИТЬ ] [ НОВАЯ ТЕМА ]
Jammardu
13.04.2020 - 14:52
Статус: Offline




Регистрация: 19.01.12
Сообщений: 4925
144
 
[^]
Yap
[x]



Продам слона

Регистрация: 10.12.04
Сообщений: 1488
 
[^]
IKA3AKI
13.04.2020 - 14:59
41
Статус: Offline


Балагур

Регистрация: 7.04.12
Сообщений: 826
Описание методов добавить бы и было бы очень интересно.
 
[^]
b0bo4ka
13.04.2020 - 15:05
21
Статус: Offline


Всё, уже никто никуда не идёт!

Регистрация: 30.07.15
Сообщений: 2101
Волшебно!
Про большую часть методов даже не слышал.
 
[^]
DMV2014
13.04.2020 - 15:06
1
Статус: Online


Хохмач

Регистрация: 23.07.14
Сообщений: 777
Аааа, спасите демоныы!!!!))))
 
[^]
пАпович
13.04.2020 - 15:06
8
Статус: Offline


тот ещё гад

Регистрация: 24.12.15
Сообщений: 668
блин, залип gigi.gif
 
[^]
terro80
13.04.2020 - 15:07
10
Статус: Offline


Хохмач

Регистрация: 18.10.14
Сообщений: 777
Теперь я знаю как в танчиках звук стрельбы записали

Это сообщение отредактировал terro80 - 13.04.2020 - 15:10

Для ЯПматематиков пост: визуализация работы 19 алгоритмов сортировки
 
[^]
TopGad
13.04.2020 - 15:08
-5
Статус: Offline


ЯПанутый

Регистрация: 23.05.11
Сообщений: 784
Тошнота и головокружение после просмотра, это нормально?
 
[^]
HellMagic
13.04.2020 - 15:09
12
Статус: Offline


Ярила

Регистрация: 13.09.15
Сообщений: 1414
Цитата (IKA3AKI @ 13.04.2020 - 14:59)
Описание методов добавить бы и было бы очень интересно.

хотяб сводную табличку - количество времени, операций сравнения, операций записи
Описание и так видно из видоса
 
[^]
Revanche
13.04.2020 - 15:09
25
Статус: Offline


Адвентист Седьмой Буквы

Регистрация: 20.04.16
Сообщений: 5721
Соглашусь с заголовком видоса- ооочень специфично.

Размещено через приложение ЯПлакалъ

Для ЯПматематиков пост: визуализация работы 19 алгоритмов сортировки
 
[^]
Eymerich
13.04.2020 - 15:16
14
Статус: Offline


Мастер добрых дел

Регистрация: 7.09.17
Сообщений: 3349
Круто. Сколько плохих методов оказывается есть.

зы а, забыл. Я так венду писал (par9)
 
[^]
Уфимский
13.04.2020 - 15:20
72
Статус: Offline


Ярила

Регистрация: 12.01.11
Сообщений: 1149
Цитата (IKA3AKI @ 13.04.2020 - 14:59)
Описание методов добавить бы и было бы очень интересно.

Сортировка пузырьком / Bubble sort

Будем идти по массиву слева направо. Если текущий элемент больше следующего, меняем их местами. Делаем так, пока массив не будет отсортирован. Заметим, что после первой итерации самый большой элемент будет находиться в конце массива, на правильном месте. После двух итераций на правильном месте будут стоять два наибольших элемента, и так далее. Очевидно, не более чем после n итераций массив будет отсортирован. Таким образом, асимптотика в худшем и среднем случае – O(n2), в лучшем случае – O(n).

***

Шейкерная сортировка / Shaker sort

(также известна как сортировка перемешиванием и коктейльная сортировка). Заметим, что сортировка пузырьком работает медленно на тестах, в которых маленькие элементы стоят в конце (их еще называют «черепахами»). Такой элемент на каждом шаге алгоритма будет сдвигаться всего на одну позицию влево. Поэтому будем идти не только слева направо, но и справа налево. Будем поддерживать два указателя begin и end, обозначающих, какой отрезок массива еще не отсортирован. На очередной итерации при достижении end вычитаем из него единицу и движемся справа налево, аналогично, при достижении begin прибавляем единицу и двигаемся слева направо. Асимптотика у алгоритма такая же, как и у сортировки пузырьком, однако реальное время работы лучше.

***

Сортировка расческой / Comb sort

Еще одна модификация сортировки пузырьком. Для того, чтобы избавиться от «черепах», будем переставлять элементы, стоящие на расстоянии. Зафиксируем его и будем идти слева направо, сравнивая элементы, стоящие на этом расстоянии, переставляя их, если необходимо. Очевидно, это позволит «черепахам» быстро добраться в начало массива. Оптимально изначально взять расстояние равным длине массива, а далее делить его на некоторый коэффициент, равный примерно 1.247. Когда расстояние станет равно единице, выполняется сортировка пузырьком. В лучшем случае асимптотика равна O(nlogn), в худшем – O(n2). Какая асимптотика в среднем мне не очень понятно, на практике похоже на O(nlogn).

***

Сортировка вставками / Insertion sort

Создадим массив, в котором после завершения алгоритма будет лежать ответ. Будем поочередно вставлять элементы из исходного массива так, чтобы элементы в массиве-ответе всегда были отсортированы. Асимптотика в среднем и худшем случае – O(n2), в лучшем – O(n). Реализовывать алгоритм удобнее по-другому (создавать новый массив и реально что-то вставлять в него относительно сложно): просто сделаем так, чтобы отсортирован был некоторый префикс исходного массива, вместо вставки будем менять текущий элемент с предыдущим, пока они стоят в неправильном порядке.

***

Сортировка Шелла / Shellsort

Используем ту же идею, что и сортировка с расческой, и применим к сортировке вставками. Зафиксируем некоторое расстояние. Тогда элементы массива разобьются на классы – в один класс попадают элементы, расстояние между которыми кратно зафиксированному расстоянию. Отсортируем сортировкой вставками каждый класс. В отличие от сортировки расческой, неизвестен оптимальный набор расстояний. Существует довольно много последовательностей с разными оценками. Последовательность Шелла – первый элемент равен длине массива, каждый следующий вдвое меньше предыдущего. Асимптотика в худшем случае – O(n2). Последовательность Хиббарда – 2n — 1, асимптотика в худшем случае – O(n1,5), последовательность Седжвика (формула нетривиальна, можете ее посмотреть по ссылке ниже) — O(n4/3), Пратта (все произведения степеней двойки и тройки) — O(nlog2n). Отмечу, что все эти последовательности нужно рассчитать только до размера массива и запускать от большего от меньшему (иначе получится просто сортировка вставками). Также я провел дополнительное исследование и протестировал разные последовательности вида si = a * si — 1 + k * si — 1 (отчасти это было навеяно эмпирической последовательностью Циура – одной из лучших последовательностей расстояний для небольшого количества элементов). Наилучшими оказались последовательности с коэффициентами a = 3, k = 1/3; a = 4, k = 1/4 и a = 4, k = -1/5.

***

Сортировка деревом / Tree sort

Будем вставлять элементы в двоичное дерево поиска. После того, как все элементы вставлены достаточно обойти дерево в глубину и получить отсортированный массив. Если использовать сбалансированное дерево, например красно-черное, асимптотика будет равна O(nlogn) в худшем, среднем и лучшем случае. В реализации использован контейнер multiset.

***

Гномья сортировка / Gnome sort

Алгоритм похож на сортировку вставками. Поддерживаем указатель на текущий элемент, если он больше предыдущего или он первый — смещаем указатель на позицию вправо, иначе меняем текущий и предыдущий элементы местами и смещаемся влево.

***

Сортировка выбором / Selection sort

На очередной итерации будем находить минимум в массиве после текущего элемента и менять его с ним, если надо. Таким образом, после i-ой итерации первые i элементов будут стоять на своих местах. Асимптотика: O(n2) в лучшем, среднем и худшем случае. Нужно отметить, что эту сортировку можно реализовать двумя способами – сохраняя минимум и его индекс или просто переставляя текущий элемент с рассматриваемым, если они стоят в неправильном порядке.

***

Пирамидальная сортировка / Heapsort

Развитие идеи сортировки выбором. Воспользуемся структурой данных «куча» (или «пирамида», откуда и название алгоритма). Она позволяет получать минимум за O(1), добавляя элементы и извлекая минимум за O(logn). Таким образом, асимптотика O(nlogn) в худшем, среднем и лучшем случае.

***

Быстрая сортировка / Quicksort

Выберем некоторый опорный элемент. После этого перекинем все элементы, меньшие его, налево, а большие – направо. Рекурсивно вызовемся от каждой из частей. В итоге получим отсортированный массив, так как каждый элемент меньше опорного стоял раньше каждого большего опорного. Асимптотика: O(nlogn) в среднем и лучшем случае, O(n2). Наихудшая оценка достигается при неудачном выборе опорного элемента. Моя реализация этого алгоритма совершенно стандартна, идем одновременно слева и справа, находим пару элементов, таких, что левый элемент больше опорного, а правый меньше, и меняем их местами. Помимо чистой быстрой сортировки, участвовала в сравнении и сортировка, переходящая при малом количестве элементов на сортировку вставками. Константа подобрана тестированием, а сортировка вставками — наилучшая сортировка, подходящая для этой задачи (хотя не стоит из-за этого думать, что она самая быстрая из квадратичных).

***

Сортировка слиянием / Merge sort

Сортировка, основанная на парадигме «разделяй и властвуй». Разделим массив пополам, рекурсивно отсортируем части, после чего выполним процедуру слияния: поддерживаем два указателя, один на текущий элемент первой части, второй – на текущий элемент второй части. Из этих двух элементов выбираем минимальный, вставляем в ответ и сдвигаем указатель, соответствующий минимуму. Слияние работает за O(n), уровней всего logn, поэтому асимптотика O(nlogn). Эффективно заранее создать временный массив и передать его в качестве аргумента функции. Эта сортировка рекурсивна, как и быстрая, а потому возможен переход на квадратичную при небольшом числе элементов.

***

Сортировка подсчетом / Counting sort

Создадим массив размера r – l, где l – минимальный, а r – максимальный элемент массива. После этого пройдем по массиву и подсчитаем количество вхождений каждого элемента. Теперь можно пройти по массиву значений и выписать каждое число столько раз, сколько нужно. Асимптотика – O(n + r — l). Можно модифицировать этот алгоритм, чтобы он стал стабильным: для этого определим место, где должно стоять очередное число (это просто префиксные суммы в массиве значений) и будем идти по исходному массиву слева направо, ставя элемент на правильное место и увеличивая позицию на 1. Эта сортировка не тестировалась, поскольку большинство тестов содержало достаточно большие числа, не позволяющие создать массив требуемого размера. Однако она, тем не менее, пригодилась

***

Блочная сортировка / Bucket sort

(также известна как корзинная и карманная сортировка). Пусть l – минимальный, а r – максимальный элемент массива. Разобьем элементы на блоки, в первом будут элементы от l до l + k, во втором – от l + k до l + 2k и т.д., где k = (r – l) / количество блоков. В общем-то, если количество блоков равно двум, то данный алгоритм превращается в разновидность быстрой сортировки. Асимптотика этого алгоритма неясна, время работы зависит и от входных данных, и от количества блоков. Утверждается, что на удачных данных время работы линейно. Реализация этого алгоритма оказалась одной из самых трудных задач. Можно сделать это так: просто создавать новые массивы, рекурсивно их сортировать и склеивать. В эффективной реализации используется несколько идей:

1) Не будем создавать новых массивов. Для этого воспользуемся техникой сортировки подсчетом – подсчитаем количество элементов в каждом блоке, префиксные суммы и, таким образом, позицию каждого элемента в массиве.
2) Не будем запускаться из пустых блоков. Занесем индексы непустых блоков в отдельный массив и запустимся только от них.
3) Проверим, отсортирован ли массив. Это не ухудшит время работы, так как все равно нужно сделать проход с целью нахождения минимума и максимума, однако позволит алгоритму ускориться на частично отсортированных данных, ведь элементы вставляются в новые блоки в том же порядке, что и в исходном массиве.
4) Поскольку алгоритм получился довольно громоздким, при небольшом количестве элементов он крайне неэффективен. До такой степени, что переход на сортировку вставками ускоряет работу примерно в 10 раз.

Осталось только понять, какое количество блоков нужно выбрать. На рандомизированных тестах мне удалось получить следующую оценку: 1500 блоков для 107 элементов и 3000 для 108. Подобрать формулу не удалось – время работы ухудшалось в несколько раз.

***

Поразрядная сортировка / Radix sort

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

***

LSD (least significant digit):

Представим каждое число в двоичном виде. На каждом шаге алгоритма будем сортировать числа таким образом, чтобы они были отсортированы по первым k * i битам, где k – некоторая константа. Из данного определения следует, что на каждом шаге достаточно стабильно сортировать элементы по новым k битам. Для этого идеально подходит сортировка подсчетом (необходимо 2k памяти и времени, что немного при удачном выборе константы). Асимптотика: O(n), если считать, что числа фиксированного размера (а в противном случае нельзя было бы считать, что сравнение двух чисел выполняется за единицу времени). Реализация довольно проста.

***

MSD (most significant digit):

На самом деле, некоторая разновидность блочной сортировки. В один блок будут попадать числа с равными k битами. Асимптотика такая же, как и у LSD версии. Реализация очень похожа на блочную сортировку, но проще. В ней используется функция digit, определенная в реализации LSD версии.

***

Битонная сортировка / Bitonic sort:

Идея данного алгоритма заключается в том, что исходный массив преобразуется в битонную последовательность – последовательность, которая сначала возрастает, а потом убывает. Ее можно эффективно отсортировать следующим образом: разобьем массив на две части, создадим два массива, в первый добавим все элементы, равные минимуму из соответственных элементов каждой из двух частей, а во второй – равные максимуму. Утверждается, что получатся две битонные последовательности, каждую из которых можно рекурсивно отсортировать тем же образом, после чего можно склеить два массива (так как любой элемент первого меньше или равен любого элемента второго). Для того, чтобы преобразовать исходный массив в битонную последовательность, сделаем следующее: если массив состоит из двух элементов, можно просто завершиться, иначе разделим массив пополам, рекурсивно вызовем от половинок алгоритм, после чего отсортируем первую часть по порядку, вторую в обратном порядке и склеим. Очевидно, получится битонная последовательность. Асимптотика: O(nlog2n), поскольку при построении битонной последовательности мы использовали сортировку, работающую за O(nlogn), а всего уровней было logn. Также заметим, что размер массива должен быть равен степени двойки, так что, возможно, придется его дополнять фиктивными элементами (что не влияет на асимптотику).

***

Timsort

Гибридная сортировка, совмещающая сортировку вставками и сортировку слиянием. Разобьем элементы массива на несколько подмассивов небольшого размера, при этом будем расширять подмассив, пока элементы в нем отсортированы. Отсортируем подмассивы сортировкой вставками, пользуясь тем, что она эффективно работает на отсортированных массивах. Далее будем сливать подмассивы как в сортировке слиянием, беря их примерно равного размера (иначе время работы приблизится к квадратичному). Для этого удобного хранить подмассивы в стеке, поддерживая инвариант — чем дальше от вершины, тем больше размер, и сливать подмассивы на верхушке только тогда, когда размер третьего по отдаленности от вершины подмассива больше или равен сумме их размеров. Асимптотика: O(n) в лучшем случае и O(nlogn) в среднем и худшем случае.

***

Отсюда...

Там ещё тестирование на разных типах данных есть и результаты сравнения по скорости и т.п.

Это сообщение отредактировал Уфимский - 13.04.2020 - 15:21
 
[^]
2медведя
13.04.2020 - 15:20
2
Статус: Offline


Ярила

Регистрация: 27.03.20
Сообщений: 1030
класс!
 
[^]
pupch
13.04.2020 - 15:25
32
Статус: Online


Весельчак

Регистрация: 17.11.14
Сообщений: 106
это ж разве визуализация? учитесь у цыган
 
[^]
IR145
13.04.2020 - 15:30
3
Статус: Offline


Ярила

Регистрация: 5.04.12
Сообщений: 7075
1) сортировка выбором
2) быстрая сортировка. Метод не знаю за основу, как я понял, берутся куски дальше и ближе некоего среднего, потом происходит окончательная сортировка
3) сортировка вставкой - нужный элемент вставляется между двумя другими
4) классическая сортировка методом "пузырька" (не водки) - эн- проходов, на каждом из которых местами меняются 2 соседних элемента, если надо. Заканчивается тога, когда перестановок больше нет.
5) Сортировка перемешиванием, или Шейкерная сортировка, или двунаправленная (англ. Cocktail sort) — разновидность пузырьковой сортировки. Анализируя метод пузырьковой сортировки, можно отметить два обстоятельства.

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

Во-вторых, при движении от конца массива к началу минимальный элемент «всплывает» на первую позицию, а максимальный элемент сдвигается только на одну позицию вправо.

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

дальше буду давать только названия - гуглится легко.

Shell Sort

Double Selection Sort

Heap Sort

Бисерная сортировка https://habr.com/ru/post/198962/

Gnome Sort https://habr.com/ru/post/145682/

Четно-нечетная сортировка https://habr.com/ru/post/414653/

Все, дальше устал...
 
[^]
lambrusco
13.04.2020 - 15:36
1
Статус: Offline


self mad man

Регистрация: 11.01.17
Сообщений: 1239
Видео не полное!
где Болотная сортировка (BogoSort) и Сортировка клоуна Бозо (BozoSort)
А?? dont.gif
 
[^]
ЯЕсть
13.04.2020 - 15:36
0
Статус: Offline


Ярила

Регистрация: 12.11.15
Сообщений: 1157
Цитата
хотяб сводную табличку - количество времени, операций сравнения, операций записи


Если ты прогер - ты и так эту таблицу знаешь (ну видел по крайней мере), а если нет - то нах она тебе не нужна cheer.gif
 
[^]
denisg2
13.04.2020 - 15:49
10
Статус: Offline


Весельчак

Регистрация: 16.07.14
Сообщений: 103
Обычно доверяю сортировку SQL серверу. "order by" решает.
 
[^]
С0крат
13.04.2020 - 16:16
3
Статус: Offline


Юморист

Регистрация: 1.04.19
Сообщений: 539
Мой внутренний перфекционист рыдал от умиления.
 
[^]
Уфимский
13.04.2020 - 16:22
5
Статус: Offline


Ярила

Регистрация: 12.01.11
Сообщений: 1149
Цитата (denisg2 @ 13.04.2020 - 15:49)
Обычно доверяю сортировку SQL серверу. "order by" решает.

Ну-ну... Давай из жителей Москвы, например, сделай сортировку по ИНН. Просто интересно: насколько сервер зависнет... shum_lol.gif
 
[^]
ELEA
13.04.2020 - 16:28
2
Статус: Offline


Ярила

Регистрация: 29.01.15
Сообщений: 5904
Цитата (b0bo4ka @ 13.04.2020 - 15:05)
Волшебно!
Про большую часть методов даже не слышал.

Большая часть из них не пригодны для практического использования. Так, для кругозора. Потому и не слышал. Я теперь вот тоже услышал, но точно использовать не стану :)
 
[^]
ЯЕсть
13.04.2020 - 16:41
5
Статус: Offline


Ярила

Регистрация: 12.11.15
Сообщений: 1157
Цитата
Ну-ну... Давай из жителей Москвы, например, сделай сортировку по ИНН. Просто интересно: насколько сервер зависнет...


Ну ок, а как сортировку организуешь ты, чтобы сервак моментально справлялся?
 
[^]
MrShelter
13.04.2020 - 16:50
12
Статус: Offline


Grammar Nazi

Регистрация: 18.06.11
Сообщений: 14539
Я подписан на несколько каналов на Ютубе с подобными визуализациями.

Ещё один факт для математиков ЯПа: девяностомиллионный комментарий был оставлен на ЯПе сегодня в 16:24.
А вот, к примеру, 80 млн.-ый – 4 апреля 2019 в 13:47, год назад.

Это сообщение отредактировал MrShelter - 13.04.2020 - 17:00
 
[^]
AVIcrak
13.04.2020 - 16:54
6
Статус: Offline


Ярила

Регистрация: 3.06.16
Сообщений: 1435
Цитата (ЯЕсть @ 13.04.2020 - 16:41)
Цитата
Ну-ну... Давай из жителей Москвы, например, сделай сортировку по ИНН. Просто интересно: насколько сервер зависнет...


Ну ок, а как сортировку организуешь ты, чтобы сервак моментально справлялся?

Считать два поля индекс и инн в отдельный массив, и уже с ним работать.
Не моментально, но сам сервер при этом не падает.
Гораздо интереснее обновлять этот массив синхронно с изменениями основной бд. Потому как встроенных средств на этот случай не предусмотрено, и каждый вояет свой оригинальный костыль.
 
[^]
124
13.04.2020 - 16:59
2
Статус: Offline


Ярила

Регистрация: 3.08.13
Сообщений: 6167
прикольно
 
[^]
Kukuzapa
13.04.2020 - 17:49
5
Статус: Offline


Приколист

Регистрация: 4.12.16
Сообщений: 350
Цитата (ЯЕсть @ 13.04.2020 - 15:36)
Цитата
хотяб сводную табличку - количество времени, операций сравнения, операций записи


Если ты прогер - ты и так эту таблицу знаешь (ну видел по крайней мере), а если нет - то нах она тебе не нужна cheer.gif

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

Мне была бы интересна сравнительная таблица.
 
[^]
Понравился пост? Еще больше интересного в Телеграм-канале ЯПлакалъ!
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии. Авторизуйтесь, пожалуйста, или зарегистрируйтесь, если не зарегистрированы.
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) Просмотры темы: 12597
0 Пользователей:
Страницы: (3) [1] 2 3  [ ОТВЕТИТЬ ] [ НОВАЯ ТЕМА ]


 
 



Активные темы






Наверх