Пирамидальная сортировка
Пирамидальная сортировка (англ. Heapsort, «Сортировка кучей»[1]) — алгоритм сортировки, работающий в худшем, в среднем и в лучшем случае (то есть гарантированно) за операций при сортировке элементов.[2] Количество применяемой служебной памяти не зависит от размера массива (то есть, ).
Может рассматриваться как усовершенствованная сортировка пузырьком, в которой элемент всплывает (min-heap) / тонет (max-heap) по многим путям.
История создания
Пирамидальная сортировка была предложена Дж. Уильямсом в 1964 году.[1]
Алгоритм
Сортировка пирамидой использует бинарное сортирующее дерево. Сортирующее дерево — это такое дерево, у которого выполнены условия:
- Каждый лист имеет глубину либо , либо , — максимальная глубина дерева.
- Значение в любой вершине не меньше (другой вариант — не больше) значения её потомков.
Удобная структура данных для сортирующего дерева — такой массив Array
, что Array[0]
— элемент в корне, а потомки элемента Array[i]
являются Array[2i+1]
и Array[2i+2]
.
Алгоритм сортировки будет состоять из двух основных шагов:
1. Выстраиваем элементы массива в виде сортирующего дерева:
при .
Этот шаг требует операций.
2. Будем удалять элементы из корня по одному за раз и перестраивать дерево. То есть на первом шаге обмениваем Array[0]
и Array[n-1]
, преобразовываем Array[0]
, Array[1]
, … , Array[n-2]
в сортирующее дерево. Затем переставляем Array[0]
и Array[n-2]
, преобразовываем Array[0]
, Array[1]
, … , Array[n-3]
в сортирующее дерево. Процесс продолжается до тех пор, пока в сортирующем дереве не останется один элемент. Тогда Array[0]
, Array[1]
, … , Array[n-1]
— упорядоченная последовательность.
Этот шаг требует операций.
Достоинства и недостатки
Достоинства
- Имеет доказанную оценку худшего случая .
- Сортирует на месте, то есть требует всего O(1) дополнительной памяти (если дерево организовывать так, как показано выше).
Недостатки
- Неустойчив — для обеспечения устойчивости нужно расширять ключ.
- На почти отсортированных массивах работает столь же долго, как и на хаотических данных.
- На одном шаге выборку приходится делать хаотично по всей длине массива — поэтому алгоритм плохо сочетается с кэшированием и подкачкой памяти.
- Методу требуется «мгновенный» прямой доступ; не работает на связанных списках и других структурах памяти последовательного доступа.
- Не распараллеливается.
Сортировка слиянием при расходе памяти O(n) быстрее ( с меньшей константой) и не подвержена деградации на неудачных данных.
Из-за сложности алгоритма выигрыш получается только на больших n. На небольших n (до нескольких тысяч) быстрее сортировка Шелла.
Применение
Алгоритм «пирамидальная сортировка» активно применяется в ядре Linux.
Примечания
- Курс лекций «Современные технологии параллельного программирования», Лекция № 5: Пирамидальная сортировка (недоступная ссылка). Дата обращения: 20 марта 2009. Архивировано 15 марта 2009 года.
- ScienceDirect — Journal of Algorithms : The Analysis of Heapsort
Литература
- Левитин А. В. Глава 6. Метод преобразования: Пирамиды и пирамидальная сортировка // Алгоритмы. Введение в разработку и анализ — М.: Вильямс, 2006. — С. 275—284. — 576 с. — ISBN 978-5-8459-0987-9
- Кормен, Т., Лейзерсон, Ч., Ривест, Р., Штайн, К. Глава 6. Пирамидальная сортировка // Алгоритмы: построение и анализ = Introduction to Algorithms / Под ред. И. В. Красикова. — 2-е изд. — М.: Вильямс, 2005. — С. 182—188. — ISBN 5-8459-0857-4.
Ссылки
- Пирамидальная сортировка — подробное описание с иллюстрациями и примером реализации на C++. Приведён вывод оценок скорости работы алгоритма и измерение времени работы на реальной вычислительной системе.
- Сортировка с помощью кучи (пирамидальная сортировка) — доходчивое описание с иллюстрациями и примером реализации на Pascal.
- Динамическая визуализация 7 алгоритмов сортировки с открытым исходным кодом