Изменения

Перейти к: навигация, поиск

Сортировка кучей

319 байт добавлено, 14:34, 28 октября 2019
Реализация
== Алгоритм ==
Необходимо отсортировать массив <tex>A</tex>, размером <tex>n</tex>. Построим на базе этого массива за <tex>O(n)</tex> кучу для максимума. Так как максимальный элемент находится в корне, то,если поменять его местами с <tex>A[n - 1]</tex>, он встанет на свое своё место. Далее вызовем процедуру <tex> \mathrm{siftDown(0)} </tex>, предварительно уменьшив <tex> \mathrm{heapSize} </tex> на <tex>1</tex>. Она за <tex>O(\log{n})</tex> просеет <tex>A[0]</tex> на нужное место и сформирует новую кучу (так как мы уменьшили ее её размер, то куча располагается с <tex>A[0]</tex> по <tex>A[n - 2]</tex>, а элемент <tex>A[n-1]</tex> находится на своем своём месте). Повторим эту процедуру для новой кучи, только корень будет менять местами не с <tex>A[n - 1]</tex>, а с <tex>A[n-2]</tex>. Делая аналогичные действия, пока <tex> \mathrm{heapSize} </tex> не станет равен <tex>1</tex>, мы будем ставить наибольшее из оставшихся чисел в конец не отсортированной части. Очевидно, что таким образом, мы получим отсортированный массив.
== Реализация ==
*<tex>\mathrm{A}</tex> {{---}} массив, который необходимо отсортировать.*<tex>\mathrm{n}</tex> {{---}} количество элементов в нем.нём*<tex> \mathrm{buildHeap(A)} </tex> {{---}} процедура, которая строит из передаваемого массива кучу для максимума в этом же массиве.*<tex> \mathrm{siftDown(A, i, len)} </tex> {{---}} процедура, которая просеивает вниз элемент <tex> \mathrm{A[i]} </tex> в куче из <tex> \mathrm{len} </tex> элементов, находящихся в начале. массива <tex> \mathrm{A} </tex>. '''fun''' heapsortheapSort(A : '''list <T>'''):
buildHeap(A)
heapSize = A.size
'''for''' i = 0 '''to''' n - 21
swap(A[0], A[n - 1 - i])
heapSize--
siftDown(A, 0, heap_sizeheapSize)
== Сложность ==
Операция <tex> \mathrm{siftDown} </tex> работает за <tex>O(\log{n})</tex>. Всего цикл выполняется <tex>(n - 1)</tex> раз. Таким образом сложность сортировки кучей является <tex>O(n\log{n})</tex>.
 
Достоинства:
* худшее время работы {{---}} <tex>O(n\log{n})</tex>,
* требует <tex>O(1)</tex> дополнительной памяти.
Недостатки:
* неустойчивая,
* на почти отсортированных данных работает столь же долго, как и на хаотических данных.
== Пример ==
|[[Файл:heap4.png|155px|thumb|Второй проход]]
|[[Файл:heap5.png|155px|thumb|Третий проход]]
|[[Файл:heap6.png|155px|thumb|Четвертый Четвёртый проход]]
|}
|-
|style="background-color:#FFF;padding:2px 10px"| '''4''' 3 2 1 5
|style="background-color:#FFF;padding:2px 10px"| Строим кучу из первых четырех четырёх элементов
|-
|colspan=3|''Второй проход''
|-
|style="background-color:#FFF;padding:2px 10px"| '''1''' 3 2 '''4''' 5
|style="background-color:#FFF;padding:2px 10px"| Меняем местами первый и четвертый четвёртый элементы
|-
|style="background-color:#FFF;padding:2px 10px"| '''3''' 1 2 4 5
|style="background-color:#FFF;padding:2px 10px"| Строим кучу из первых трех трёх элементов
|-
|colspan=3|''Третий проход''
|style="background-color:#FFF;padding:2px 10px"| Строим кучу из двух элементов
|-
|colspan=3|''Четвертый Четвёртый проход''
|-
|style="background-color:#FFF;padding:2px 10px"| '''1''' '''2''' 3 4 5
= JSort =
'''JSort''' является модификацией сортировки кучей, которую придумал Джейсон Моррисон (''Jason Morrison'').
Алгоритм частично упорядочивает массив, строя на нем нём два раза кучу: один раз передвигая меньшие элементы влево, второй раз передвигая большие элементы вправо. Затем к массиву применяется[[Сортировка вставками|сортировка вставками]], которая при почти отсортированных данных работает за <tex>O(n)</tex>.
Достоинства:
отличии отличие от сортировки кучей, на почти отсортированных массивах работает быстрее, чем на случайных.
*В силу использования сортировки вставками, которая просматривает элементы последовательно, использование кэша гораздо эффективнее.
Недостатки:
Построим кучу для минимума на этом массиве.
Тогда наименьший элемент окажется на первой позиции, а левая часть массива окажется почти отсортированной, так как ей будут соответствовать верхние узлы кучи.
Теперь построим на этом же массиве кучу так, чтобы немного упорядочить правую часть массива. Эта куча должна быть кучей для максимума и быть "зеркальной" к массиву, то есть чтобы ее её корень соответствовал последнему элементу массива.
К получившемуся массиву применим сортировку вставками.
=== Сложность ===
Постройка Построение кучи занимает <tex>O(n)</tex>. Почти упорядоченный массив сортировка вставками может отсортировать <tex> O(n)</tex>, но в худшем случае за <tex>O(n^2)</tex> в худшем.
Таким образом в худшем случае сложность JSort является , наихудшая оценка Jsort {{---}} <tex>O(n^2)</tex>.
=== Пример ===
Рассмотрим, массив <tex> A </tex> = <tex> ([1, 2, 8, 15, 17, 20, 31, 32, 30, 2, 3, 5, 10, 11, 24 ) ] </tex>
Построим на этом массиве кучу для минимума:
| [[Файл:HeapW.png|400px]]
|}
Сам массив же будет выглядеть Массив выглядит следующим образом:
{| cellpadding="3" style="margin-left: left; margin-right: left;"
| [[Файл:HeapM.png|400px]]
| [[Файл:HeapWU.png|400px]]
|}
Сам массив же Массив будет выглядеть следующим образом:
{| cellpadding="3" style="margin-left: left; margin-right: left;"
| [[Файл:HeapMU.png|400px]]
Анонимный участник

Навигация