alex_dz, оптимизация. Чтобы не нагружала проц в момент паузы, там цикл гоняется, если в режиме паузы. Да там же по коментам понятно.
Я думал что пузырёк самый медленный из реальных сортировок(Bogo не в счёт), но оказалось ещё более медленная, это Stooge sort, зависимость почти кубическая, аж [math]O(n^{2.7095})[/math]. Это медленно, я добавил этот алгоритм, и мне пришлось задержку давать в части обмена, иначе очень медленно работает, устанете ждать.
Дурацкая сортировка«Дурацкая сортировка», она же «stupid sort» ― относится к классу «сортировок обменом». Сложность сортировки в лучшем, среднем и худшем случае [math]O(n^{3})[/math] (постоянство ― признак мастерства ). Просматривается массив, начиная с первого элемента, по пути сравниваются соседние элементы. Если находят неотсортированную пару ― элементы меняются местами, происходит возврат в начало массива и всё повторяется. Процесс заканчивается, если добрались до последнего элемента массива. В аттаче asm-/rc-/exe-файлы и курсор
Придурковатая сортировка Она же «сортировка по частям», она же «блуждающая сортировка» ― относится к классу «сортировок обменом». Сложность сортировки в лучшем, среднем и худшем случае [math]O(n^{\frac{\displaystyle log_{2}(3)}{\displaystyle log_{2}(1,5)}})\approx O(n^{2,70951})[/math]. Сортировка названа в честь американской комик-группы «Three stooges» («Три придурка»). Коллектив трио периодически менялся. В алгоритм заложен элемент абсурда ― обычно массив давно отсортирован, но сортировка продолжает безумно метаться по третям массива. Сравнивают элементы в начале и конце подмассива (первоначально это весь массив). Если значение элемента в начале массива больше чем у элемента в конце массива, тогда элементы меняют местами. Рекурсивно применяют сортировку для первых 2/3 элементов массива. Рекурсивно применяют сортировку для последних 2/3 элементов массива. Снова рекурсивно применяют сортировку для первых 2/3 элементов массива В аттаче asm-/rc-/exe-файлы и курсор
Вот ещё добавил три штуки. Интересная сортировка CountingSort, очень быстрая(быстрей квика), зависимость равна O(n), но есть ограничения, надо знать диапазон чисел, работает только с целыми, и диапазон должен быть не очень большой, но в некоторых случаях это что нужно, например сортировка номеров, там диапазон ограничен. И ещё CycleSort, там количество записей равно O(n), что используется если у нас флэшпамять. ЗЫ Ах да, антивири ругаются, аж 9 штук, но потом один передумал. --- Сообщение объединено, 5 янв 2023 --- Mikl___, что-то мерцает форма! Может лучше моим методом отрисовывать?, у меня ничего не мерцает. --- Сообщение объединено, 5 янв 2023 --- На ноутбуке тоже мерцает, монитор 60 Гц. Может на более высокочастотных не мерцает?
Сортировка подсчетом Она же «Counting sort» ― относится к классу «сортировок подсчетом». Вычисляется значения максимального [math]max[/math] элемента массива. Выделяется вспомогательный массив [math]count[0...k][/math], заполненный нулями, где [math]k=max.[/math] Подсчитывается сколько раз в сортируемом массиве [math]A[/math] встречается каждое значение и для каждого [math]A[i][/math] увеличивается [math]count[A[i]][/math] на единицу. Проходят по массиву [math]count[/math], [math]j\in\{0,...,k\}[/math] в массив [math]A[/math] последовательно записывают число [math]j[/math] столько раз, сколько указано в ячейке [math]count[j].[/math] Сложность сортировки в лучшем случае [math]O(n)[/math], в среднем и худшем случае [math]O(n+k)[/math] В аттаче asm-/rc-/exe-файлы и курсор
Цикличная сортировка или семь раз отмерь (cmp) ― один отрежь (swap) Она же «Cycle sort» ― относится к классу «сортировок выбором». Сложность сортировки в лучшем, среднем и худшем случае [math]O(n^{2})[/math] Выбирается очередной элемент. Для него отыскивается подходящее место в массиве. Элемент помещается в найденное место, а элемент, который занимал нужное место, извлекается и новое расположение ищется теперь для него... Продолжаем, пока на найдем элемент, который нужно положить на место того, с которого начали. Круг замкнулся. Циклы повторяются для каждого элемента массива слева направо. На i-й итерации все элементы левее i-го уже стоят на своих местах. Анализировать нужно только тех, кто правее i-й позиции. Чтобы определить правильное место, элемента, достаточно посчитать, сколько элементов меньше него (на сколько позиций правее он должен быть). Большое количество сравнений обычно делает этот алгоритм не слишком эффективным. Его область применения ― задачи в которых велика «стоимость» записи в массив. Цикличная сортировка ценна тем, что изменения среди элементов массива происходят только в случаях, когда элемент ставится на своё место. Это важно, если перезапись в массиве обходится слишком «дорого» и актуальны минимальные изменения в физической памяти. Количество перестановок в этом алгоритме минимально. В аттаче asm-/rc-/exe-файлы и курсор.
Пытался вот этот код использовать, отладил на UASM. Спойлер Код (ASM): node_t struct ;(sizeof=12, align=4) item sdword ? ;int prev dword ? ;*node_t next dword ? ;*node_t node_t ends sizeof@node_t = sizeof(node_t) align_proc list_initialize proc list:ptr node_t ASSUME edx:ptr node_t, ebx:ptr node_t, edi:ptr node_t mov edx, list mov [edx].prev, edx mov [edx].next, edx ret list_initialize endp align_proc list_destroy proc uses esi edi ebx list:ptr node_t mov ebx, list mov edi, [ebx].next ;n .while (edi != ebx) mov esi, [edi].next ;tmp hfree(edi) mov edi, esi .endw ASSUME edx:nothing ret list_destroy endp align_proc list_append_node proc list:ptr node_t, node:ptr node_t ASSUME eax:ptr node_t, edx:ptr node_t, ecx:ptr node_t mov edx, list mov ecx, node mov eax, [edx].prev ;prev mov [eax].next, ecx mov [edx].prev, ecx mov [ecx].prev, eax mov [ecx].next, edx ASSUME eax:nothing ret list_append_node endp align_proc list_append_item proc list:ptr node_t, item:sdword mov ecx, halloc(sizeof@node_t) ;node mrm [ecx].item, item list_append_node(list, ecx) ret list_append_item endp align_proc list_print proc uses esi edi list:ptr node_t mov edi, list printf("[") mov esi, [edi].next ;n .if (esi != edi) printf("%d", [esi].item) mov esi, [esi].next .endif .for (: esi != edi: esi = [esi].next) printf(", %d", [esi].item) .endfor printf("]\n") ret list_print endp align_proc tree_insert proc uses ebx p:ptr ptr node_t, n:ptr node_t ASSUME edx:ptr dword, ecx:ptr node_t mov edx, p mov ecx, n .while ([edx] != NULL) mov ebx, [edx] mov eax, [ebx].item .if ([ecx].item < eax) lea edx, [ebx].prev .else lea edx, [ebx].next .endif .endw mov [edx], ecx ret tree_insert endp align_proc tree_to_list proc uses esi edi ebx list:ptr node_t, node:ptr node_t ASSUME edi:ptr node_t, esi:ptr node_t mov ebx, list mov edi, node .if (edi) mov esi, [edi].next ;next tree_to_list(ebx, [edi].prev) list_append_node(ebx, edi) tree_to_list(ebx, esi) .endif ret tree_to_list endp align_proc tree_sort proc uses esi edi ebx list:ptr node_t local root:ptr node_t mov esi, list mov edi, [esi].next ;n .if (edi != esi) and root, NULL .while (edi != esi) mov ebx, [edi].next ;next xor eax, eax mov [edi].next, eax mov [edi].prev, eax tree_insert(&root, edi) mov edi, ebx .endw list_initialize(esi) tree_to_list(esi, root) .endif ASSUME edi:nothing, esi:nothing, ecx:nothing, ebx:nothing ret tree_sort endp align_proc TreeSort proc dummy:dword local list:node_t mov g_bActiveProcces, true ASSUME esi:ptr node_t list_initialize(&list) tree_sort(&list) list_destroy(&list) ASSUME esi:nothing xor eax, eax mov g_bActiveProcces, al ;=false mov g_bPause, al ;=false ret TreeSort endp Код работает, но как его в демку засунуть, хрен его знает?!?!?!?! ЗЫ А антивири таки дорабатывают, ну дежурные программисты таки водку на рабочем месте не жрут, а работают. В общем сейчас только 5 антивиря детектят вредоноса, всего-то надо ида-про открыть фыйл и быстро убедится в безопасности файла.
Гравитационная сортировка Она же «сортировка бусинами», она же «сортировка абаком», она же «Bead Sort» ― относится к классу «сортировок распределением». Операции сравнения используются при поиске максимального элемента, чтобы потом выделить дополнительную память [math]max\times n[/math], где [math]n[/math] — количество элементов в массиве. Сложность по времени: [math]O(\sqrt {n})[/math], где [math]n[/math] — количество рядов — В реалистичной симуляции гравитации время, затрачиваемое на расчет падения бусин, прямо пропорционально квадратному корню из количества рядов. [math]O(n)[/math] — Бусины просчитываются по одному ряду за раз. [math]O(S)[/math], где [math]S[/math] — сумма всех чисел в изначальном массиве — Каждая бусина просчитывается индивидуально. В аттаче asm-/rc-/exe-файлы и курсор
Ещё добавил сортировок. TreeSort не получилось анимацию, но видно что это быстрая сортировка, хотя я думал как пузырёк, но зависимость [math]O(log_{2}(n))[/math] и сам код простой. Добавил просто для примера. ЗЫ Ещё переделал отрисовку, теперь рисуется непосредственно на основную форму, это быстрей (совсем нет мерцаний) и меньше памяти требует. --- Сообщение объединено, 9 янв 2023 --- Нашёл ультрамедленную сортировку! Выдала аж 19 млн сравнений, при 150 чисел, хотя перемещений столько, сколько в пузырьке. https://ru.wikipedia.org/wiki/Медленная_сортировка Дурацкая по ходу быстрей, потом код выложу.
Сортировка деревомОна же «сортировка с помощью бинарного дерева», она же «tree sort» — относится к классу «сортировок вставками». Алгоритм сортировки, заключающийся в построении двоичного дерева поиска. Первый элемент — корень дерева, остальные добавляются по следующему принципу — начиная с корня дерева, элемент сравнивается с узлами, если элемент меньше чем узел — тогда спускаемся по левой ветке, если не меньше — тогда по правой. Спустившись до конца, элемент сам становится узлом. Построенное таким образом дерево можно легко обойти так, чтобы двигаться от узлов с меньшими значениями к узлам с большими значениями. При этом получаем все элементы в возрастающем порядке. Сортировка является оптимальной при получении данных путем непосредственного чтения из потока (файла, сокета или консоли). Процедура добавления [math]n[/math] объектов в бинарное дерево имеет среднюю алгоритмическую сложность порядка [math]O(n\cdot log_{2}(n))[/math], что относит сортировку к группе «быстрых сортировок». Cложность добавления одного объекта в разбалансированное дерево может достигать [math]O(n)[/math], что для [math]n[/math] элементов приведет к общей сложности порядка [math]O(n^{2})[/math]. Сложность сортировки в лучшем и среднем случае [math]O(n\cdot log_{2}(n))[/math], в худшем случае [math]O(n^{2})[/math]. Сложность сортировки по памяти [math]O(4\cdot n)[/math] — при развертывании древовидной структуры в памяти требуется не менее чем [math]4n[/math] ячеек дополнительной памяти (каждый узел должен содержать ссылки на элемент исходного массива, на родительский элемент, на левый и правый лист), существуют способы уменьшить требуемую дополнительную память. В аттаче asm-/rc-/exe-файлы и курсор
Добавил пару сортировок крайне медленную SlowSort и довольно быструю BitonicSort, но требуется размер массива степени двойки. Решил так же и потестировать код, на хабре много статей, но нет тестов на ассемблере, что быстрей, ассемблер или C/C++ т.е. сортировка контейнеров со сложными типами данных и как следствия, всяким шаблонным программированием на плюсах в новых редакциях. Для меня шаблоны на плюсах дикий лес, практически не понимаю, только что-то очень просто на старых плюсах. По предварительным данным, вроде не самая быстрая CombSort показывает хороший результат.
Intro, а с чем связано то, что для нормальной работы BitonicSort значение ArraySize должно быть 2N? Заменой деления на сдвиги?
Код взял на хабре. https://habr.com/ru/post/335920/ Спойлер Идея данного алгоритма заключается в том, что исходный массив преобразуется в битонную последовательность – последовательность, которая сначала возрастает, а потом убывает. Ее можно эффективно отсортировать следующим образом: разобьем массив на две части, создадим два массива, в первый добавим все элементы, равные минимуму из соответственных элементов каждой из двух частей, а во второй – равные максимуму. Утверждается, что получатся две битонные последовательности, каждую из которых можно рекурсивно отсортировать тем же образом, после чего можно склеить два массива (так как любой элемент первого меньше или равен любого элемента второго). Для того, чтобы преобразовать исходный массив в битонную последовательность, сделаем следующее: если массив состоит из двух элементов, можно просто завершиться, иначе разделим массив пополам, рекурсивно вызовем от половинок алгоритм, после чего отсортируем первую часть по порядку, вторую в обратном порядке и склеим. Очевидно, получится битонная последовательность. Асимптотика: O(nlog2n), поскольку при построении битонной последовательности мы использовали сортировку, работающую за O(nlogn), а всего уровней было logn. Также заметим, что размер массива должен быть равен степени двойки, так что, возможно, придется его дополнять фиктивными элементами (что не влияет на асимптотику). Такая реализация, сам до конца не понимаю. Но лучше в демке сделать 128, 256 многовато, конечно работает и другими размерами, если дополнить фиктивными элементами, но в демке это не очень выглядит.
Битонная сортировка «Битонная сортировка», она же «bitonic sort» ― относится к классу «параллельных сортировок». Сложность сортировки в лучшем, среднем и худшем случае [math]O(n\cdot log_{2}^{2}(n))[/math] Алгоритм основан на понятии битонных последовательностей и операций над ними. Битонной последовательностью называют последовательность, которая монотонно не убывает, а затем монотонно не возрастает. Чтобы превратить любую битонную последовательность в отсортированную, нужно: Разделить последовательность пополам, попарно сравнить элементы [math]x_{i}[/math] и [math]x_{\frac{n}{2}+i}[/math], меняя их местами, если элемент из первой половины больше (или меньше). Рекурсивно выполнить эту сортировку над каждой из получившихся половин. Чтобы превратить произвольную последовательность в битонную, нужно: Разделить последовательность пополам. Первую часть превратить в битонную последовательность и отсортировать по возрастанию. Вторую часть превратить в битонную и отсортировать по убыванию. РеализацияРазобьем массив на две части, в первый подмассив добавим все элементы, равные минимуму из соответственных элементов каждой из двух частей, а во второй – равные максимуму. Получатся две битонные последовательности, каждую из которых можно рекурсивно отсортировать тем же образом, после чего можно склеить два массива (так как любой элемент первого меньше или равен любого элемента второго). Для того, чтобы преобразовать исходный массив в битонную последовательность: если массив состоит из двух элементов – завершаемся, иначе делим массив пополам, рекурсивно вызовем от половинок алгоритм, после чего отсортируем первую часть по порядку, вторую в обратном порядке и склеиваем массивы.Временная сложность Сортировка рекурсивно разбивается на [math]log_{2}(n)[/math] уровней. Каждый рекурсивный вызов уменьшает размер подмассива в 2 раза, при этом количество таких подмассивов в два раза увеличивается. Сначала сравниваются [math]\frac{n}{2}[/math] пар, затем[math]\frac{n}{4}[/math] в одной половине массива и [math]\frac{n}{4}[/math] в другой, и так далее... [math]\frac{n}{2}+2\frac{n}{4}+4\frac{n}{8}+...=\frac{n}{2}\times log_{2}(n)[/math] Общее количество сравнений равно [math]\frac{n}{2}log_{2}(n)[/math] В аттаче asm-/rc-/exe-файлы и курсор
Но видов деревьев, подходящих для сортировки много. Мне больше нравится, как пример "6.3 Цифровой поиск... Бинарный случай..." Д. Кнут т.3 1978г стр. 581. Но и не обязательно бинарный. 4,8,16...
Вот бы как-то строковые сортировки анимировать, можно не только буквами, но цветными блоками, но надо думать.
R81..., но я же не Дональд Кнут А если серьезно, названия у каких сортировок нужно поправить, какие более правильные определения должны быть? Напишите, можно в личку, я поправлю