Сортировка кучей — различия между версиями
Строка 1: | Строка 1: | ||
− | '''Сортировка кучей''', '''пирамидальная сортировка''' (англ. '''Heapsort''') {{---}} алгоритм сортировки, использующий структуру данных [[Двоичная куча|двоичная куча]]. Это нестабильный алгоритм сортировки с | + | '''Сортировка кучей''', '''пирамидальная сортировка''' (англ. '''Heapsort''') {{---}} алгоритм сортировки, использующий структуру данных [[Двоичная куча|двоичная куча]]. Это нестабильный алгоритм сортировки с временем работы <tex>O(n\log{n})</tex> , где <tex>n</tex> {{---}} количество элементов для сортировки, и использующий <tex>O(1)</tex> дополнительной памяти. |
== Алгоритм == | == Алгоритм == | ||
− | Необходимо отсортировать массив <tex>A</tex>, размером <tex>n</tex>. Построим на базе этого массива за <tex>O(n)</tex> невозрастающую кучу. Так как по свойству кучи максимальный элемент находится в корне, то, поменявшись его местами с <tex>A[n - 1]</tex>, он встанет на свое место. Далее вызовем процедуру '''sift_down(0)''', предварительно уменьшив <tex>heap\_size</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>A</tex>, размером <tex>n</tex>. Построим на базе этого массива за <tex>O(n)</tex> невозрастающую кучу. Так как по свойству кучи максимальный элемент находится в корне, то, поменявшись его местами с <tex>A[n - 1]</tex>, он встанет на свое место. Далее вызовем процедуру '''sift_down(0)''', предварительно уменьшив <tex>heap\_size</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>heap_size</tex> не станет равен <tex>1</tex>, мы будем ставить наибольшее из оставшихся чисел в конец не отсортированной части. Очевидно, что таким образом, мы получим отсортированный массив. |
== Реализация == | == Реализация == | ||
+ | <tex>A</tex> {{---}} массив, который необходимо отсортировать; <tex>n</tex> {{---}} количество элементов в нем; '''build_heap(A)''' - процедура, которая строит из передаваемого массива невозрастающую кучу в этом же массиве; '''sift_down(A, i, len)''' {{---}} процедура, которая просеивает вниз элемент <tex>A[i]</tex> в куче из <tex>len</tex> элементов, находящихся в начале массива <tex>A</tex>. | ||
<pre> | <pre> | ||
heapsort(A) | heapsort(A) | ||
Строка 12: | Строка 13: | ||
swap(A[0], A[n - 1 - i]); | swap(A[0], A[n - 1 - i]); | ||
heap_size--; | heap_size--; | ||
− | sift_down(0, heap_size); | + | sift_down(A, 0, heap_size); |
</pre> | </pre> | ||
+ | |||
+ | == Сложность == | ||
+ | Операция '''sift_down''' работает за <tex>O(\log{n})</tex>. Всего цикл выполняется <tex>n - 1</tex> раз. Таким образом сложность сортировки кучей является <tex>O(n\log{n})</tex>. | ||
+ | |||
+ | |||
== Пример == | == Пример == | ||
Строка 60: | Строка 66: | ||
== Ссылки == | == Ссылки == | ||
− | *[http://ru.wikipedia.org/wiki/%D0% | + | *[http://ru.wikipedia.org/wiki/%D0%9F%D0%B8%D1%80%D0%B0%D0%BC%D0%B8%D0%B4%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%81%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0 Сортировка кучей в русской википедии] |
+ | *[http://en.wikipedia.org/wiki/Heapsort Сортировка кучей в английской википедии] | ||
== Литература == | == Литература == |
Версия 08:09, 3 июня 2012
Сортировка кучей, пирамидальная сортировка (англ. Heapsort) — алгоритм сортировки, использующий структуру данных двоичная куча. Это нестабильный алгоритм сортировки с временем работы , где — количество элементов для сортировки, и использующий дополнительной памяти.
Содержание
Алгоритм
Необходимо отсортировать массив
, размером . Построим на базе этого массива за невозрастающую кучу. Так как по свойству кучи максимальный элемент находится в корне, то, поменявшись его местами с , он встанет на свое место. Далее вызовем процедуру sift_down(0), предварительно уменьшив на . Она за просеет на нужное место и сформирует новую кучу (так как мы уменьшили ее размер, то куча располагается с по , а элемент находится на своем месте). Повторим эту процедуру для новой кучи, только корень будет менять местами не с , а с . Делая аналогичные действия, пока не станет равен , мы будем ставить наибольшее из оставшихся чисел в конец не отсортированной части. Очевидно, что таким образом, мы получим отсортированный массив.Реализация
— массив, который необходимо отсортировать; — количество элементов в нем; build_heap(A) - процедура, которая строит из передаваемого массива невозрастающую кучу в этом же массиве; sift_down(A, i, len) — процедура, которая просеивает вниз элемент в куче из элементов, находящихся в начале массива .
heapsort(A) build_heap(A); heap_size = A.size; for i:= 0 to n - 2 swap(A[0], A[n - 1 - i]); heap_size--; sift_down(A, 0, heap_size);
Сложность
Операция sift_down работает за
. Всего цикл выполняется раз. Таким образом сложность сортировки кучей является .
Пример
Пусть дана последовательность из
элементов .Массив | Описание шага | |
---|---|---|
Первый проход (текущий массив начинается с первого элемента) | ||
5 4 1 2 3 | Находим первый минимальный элемент — 1 | |
1 4 5 2 3 | Меняем минимальный и первый элементы местами | |
Второй проход (текущий массив начинается со следующего элемента) | ||
1 5 4 2 3 | Находим следующий минимальный элемент — 2 | |
1 2 4 5 3 | Меняем минимальный и второй элементы местами | |
Третий проход (текущий массив начинается со следующего элемента) | ||
1 2 4 5 3 | Находим следующий минимальный элемент — 3 | |
1 2 3 5 4 | Меняем минимальный и третий элементы местами | |
Четвертый проход (текущий массив начинается со следующего элемента) | ||
1 2 3 5 4 | Находим следующий минимальный элемент — 4 | |
1 2 3 4 5 | Меняем минимальный и четвертый элементы местами | |
1 2 3 4 5 | Массив отсортирован |
Ссылки
Литература
- Кормен Т., Лейзерсон Ч., Ривест Р., Штайн К. Алгоритмы: построение и анализ, 2-е издание. М.: Издательский дом "Вильямс", 2005. ISBN 5-8459-0857-4