Изменения

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

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

191 байт добавлено, 19:51, 16 апреля 2015
м
Сложность
== Алгоритм ==
Необходимо отсортировать массив <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
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> дополнительной памяти.
Недостатки:
* неустойчивая,
* на почти отсортированных данных работает столь же долго, как и на хаотических данных.
== Пример ==
= JSort =
'''JSort''' является модификацией сортировки кучей, которую придумал Джейсон Моррисон (''Jason Morrison'').
Алгоритм частично упорядочивает массив, строя на нем два раза кучу: один раз передвигая меньшие элементы влево, второй раз передвигая большие элементы вправо.Затем к массиву применяетсяДосортировав массив [[Сортировка вставками|сортировкой сортировка вставками]], можно получить временную сложность которая при почти отсортированных данных работает за <tex>O(n)</tex> в лучшем случае.  Сортировка кучей обладает двумя большими недостатками:*Невозможность использования кэша, так как наше движение по массиву в чем-то похоже на хаотичное.*На почти отсортированных массивах работает столь же долго, как и на хаотических данных.
Так как в Jsort Достоинства:*В отличие от сортировки кучей, на почти отсортированных массивах работает быстрее, чем на последнем этапе используется сортировка случайных.*В силу использования сортировки вставками, то это частично решает проблемы сортировки кучейкоторая просматривает элементы последовательно, использование кэша гораздо эффективнее. Почти Недостатки:*На длинных массивах, возникают плохо отсортированные данные сортируются за линейное времяпоследовательности в середине массива, что приводит к ухудшению работы сортировки вставками.
=== Алгоритм ===
 Необходимо отсортировать массив.Построим невозрастающую кучу для минимума на этом массиве.
Тогда наименьший элемент окажется на первой позиции, а левая часть массива окажется почти отсортированной, так как ей будут соответствовать верхние узлы кучи.
Теперь построим на этом же массиве кучу так, чтобы немного упорядочить правую часть массива. Эта куча должна быть неубывающей кучей для максимума и быть "зеркальной" к массиву, то есть чтобы ее корень соответствовал последнему элементу массива.Получившийся почти отсортированный массив досортируем сортировкой К получившемуся массиву применим сортировку вставками.
=== Сложность ===
Постройка Построение кучи занимает <tex>O(n)</tex>. Почти упорядоченный массив сортировка вставками может отсортировать <tex> O(n)</tex>, но в худшем случае за <tex>O(n^2)</tex> в худшем.
Таким образом в худшем случае сложность JSort является , наихудшая оценка Jsort {{---}} <tex>O(n^2)</tex>, а в лучшем <tex>O(n)</tex>.
=== Пример ===
Рассмотрим, массив <tex> A </tex> = <tex> ([1, 2, 8, 15, 17, 20, 31, 32, 30, 2, 3, 5, 10, 11, 24 ) ] </tex> Построим на этом массиве невозрастающую кучудля минимума:
{| cellpadding="3" style="margin-left: left; margin-right: left;"
| [[Файл:HeapW.png|400px]]
|}
Сам массив же будет выглядеть Массив выглядит следующим образом:
{| cellpadding="3" style="margin-left: left; margin-right: left;"
| [[Файл:HeapM.png|400px]]
Заметим, что начало почти упорядочено, что хорошо скажется на использовании сортировки вставками.
Построим теперь зеркальную неубывающую кучу для максимума на этом же массиве.
{| cellpadding="3" style="margin-left: left; margin-right: left;"
| [[Файл:HeapWU.png|400px]]
|}
Сам массив же Массив будет выглядеть следующим образом:
{| cellpadding="3" style="margin-left: left; margin-right: left;"
| [[Файл:HeapMU.png|400px]]

Навигация