<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=95.58.179.186&amp;*</id>
		<title>Викиконспекты - Вклад участника [ru]</title>
		<link rel="self" type="application/atom+xml" href="http://neerc.ifmo.ru/wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=95.58.179.186&amp;*"/>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/95.58.179.186"/>
		<updated>2026-05-09T04:51:30Z</updated>
		<subtitle>Вклад участника</subtitle>
		<generator>MediaWiki 1.30.0</generator>

	<entry>
		<id>http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BA%D1%83%D1%87%D0%B5%D0%B9&amp;diff=71904</id>
		<title>Сортировка кучей</title>
		<link rel="alternate" type="text/html" href="http://neerc.ifmo.ru/wiki/index.php?title=%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%BA%D1%83%D1%87%D0%B5%D0%B9&amp;diff=71904"/>
				<updated>2019-10-28T11:34:52Z</updated>
		
		<summary type="html">&lt;p&gt;95.58.179.186: /* Реализация */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Сортировка кучей''', '''пирамидальная сортировка''' (англ. ''Heapsort'') {{---}} алгоритм сортировки, использующий структуру данных [[Двоичная куча|двоичная куча]]. Это неустойчивый алгоритм сортировки с временем работы &amp;lt;tex&amp;gt;O(n\log{n})&amp;lt;/tex&amp;gt; , где &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt; {{---}} количество элементов для сортировки, и использующий &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; дополнительной памяти.&lt;br /&gt;
&lt;br /&gt;
== Алгоритм ==&lt;br /&gt;
Необходимо отсортировать массив &amp;lt;tex&amp;gt;A&amp;lt;/tex&amp;gt;, размером &amp;lt;tex&amp;gt;n&amp;lt;/tex&amp;gt;. Построим на базе этого массива за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt; кучу для максимума. Так как максимальный элемент находится в корне, то если поменять его местами с &amp;lt;tex&amp;gt;A[n - 1]&amp;lt;/tex&amp;gt;, он встанет на своё место. Далее вызовем процедуру &amp;lt;tex&amp;gt; \mathrm{siftDown(0)} &amp;lt;/tex&amp;gt;, предварительно уменьшив &amp;lt;tex&amp;gt; \mathrm{heapSize} &amp;lt;/tex&amp;gt; на &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;. Она за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt; просеет &amp;lt;tex&amp;gt;A[0]&amp;lt;/tex&amp;gt; на нужное место и сформирует новую кучу (так как мы уменьшили её размер, то куча располагается с &amp;lt;tex&amp;gt;A[0]&amp;lt;/tex&amp;gt; по &amp;lt;tex&amp;gt;A[n - 2]&amp;lt;/tex&amp;gt;, а элемент &amp;lt;tex&amp;gt;A[n-1]&amp;lt;/tex&amp;gt; находится на своём месте). Повторим эту процедуру для новой кучи, только корень будет менять местами не с &amp;lt;tex&amp;gt;A[n - 1]&amp;lt;/tex&amp;gt;, а с &amp;lt;tex&amp;gt;A[n-2]&amp;lt;/tex&amp;gt;. Делая аналогичные действия, пока &amp;lt;tex&amp;gt; \mathrm{heapSize}  &amp;lt;/tex&amp;gt; не станет равен &amp;lt;tex&amp;gt;1&amp;lt;/tex&amp;gt;, мы будем ставить наибольшее из оставшихся чисел в конец не отсортированной части. Очевидно, что таким образом, мы получим отсортированный массив.&lt;br /&gt;
&lt;br /&gt;
== Реализация ==&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{A}&amp;lt;/tex&amp;gt; {{---}} массив, который необходимо отсортировать&lt;br /&gt;
*&amp;lt;tex&amp;gt;\mathrm{n}&amp;lt;/tex&amp;gt; {{---}} количество элементов в нём&lt;br /&gt;
*&amp;lt;tex&amp;gt; \mathrm{buildHeap(A)} &amp;lt;/tex&amp;gt; {{---}} процедура, которая строит из передаваемого массива кучу для максимума в этом же массиве&lt;br /&gt;
*&amp;lt;tex&amp;gt; \mathrm{siftDown(A, i, len)} &amp;lt;/tex&amp;gt; {{---}} процедура, которая просеивает вниз элемент &amp;lt;tex&amp;gt; \mathrm{A[i]} &amp;lt;/tex&amp;gt; в куче из &amp;lt;tex&amp;gt; \mathrm{len} &amp;lt;/tex&amp;gt; элементов, находящихся в начале массива &amp;lt;tex&amp;gt; \mathrm{A} &amp;lt;/tex&amp;gt;&lt;br /&gt;
  '''fun''' heapSort(A : '''list &amp;lt;T&amp;gt;'''):&lt;br /&gt;
    buildHeap(A)&lt;br /&gt;
    heapSize = A.size&lt;br /&gt;
    '''for''' i = 0 '''to''' n - 1&lt;br /&gt;
      swap(A[0], A[n - 1 - i])&lt;br /&gt;
      heapSize--&lt;br /&gt;
      siftDown(A, 0, heapSize)&lt;br /&gt;
&lt;br /&gt;
== Сложность ==&lt;br /&gt;
Операция &amp;lt;tex&amp;gt; \mathrm{siftDown} &amp;lt;/tex&amp;gt; работает за &amp;lt;tex&amp;gt;O(\log{n})&amp;lt;/tex&amp;gt;. Всего цикл выполняется &amp;lt;tex&amp;gt;(n - 1)&amp;lt;/tex&amp;gt; раз. Таким образом сложность сортировки кучей является &amp;lt;tex&amp;gt;O(n\log{n})&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Достоинства:&lt;br /&gt;
* худшее время работы {{---}} &amp;lt;tex&amp;gt;O(n\log{n})&amp;lt;/tex&amp;gt;,&lt;br /&gt;
* требует &amp;lt;tex&amp;gt;O(1)&amp;lt;/tex&amp;gt; дополнительной памяти.&lt;br /&gt;
Недостатки:&lt;br /&gt;
* неустойчивая,&lt;br /&gt;
* на почти отсортированных данных работает столь же долго, как и на хаотических данных.&lt;br /&gt;
&lt;br /&gt;
== Пример ==&lt;br /&gt;
&lt;br /&gt;
{|align=&amp;quot;right&amp;quot;&lt;br /&gt;
 |-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
 |[[Файл:heap1.png|155px|thumb|Строим кучу]]&lt;br /&gt;
 |[[Файл:heap2.png|155px|thumb|Первый проход]]&lt;br /&gt;
 |[[Файл:heap3.png|155px|thumb|Строим новую кучу]]&lt;br /&gt;
 |-&lt;br /&gt;
 |[[Файл:heap4.png|155px|thumb|Второй проход]]&lt;br /&gt;
 |[[Файл:heap5.png|155px|thumb|Третий проход]]&lt;br /&gt;
 |[[Файл:heap6.png|155px|thumb|Четвёртый проход]]&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
Пусть дана последовательность из &amp;lt;tex&amp;gt;5&amp;lt;/tex&amp;gt; элементов &amp;lt;tex&amp;gt;3, 2, 4, 1, 5&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;background-color:#CCC;margin:0.5px&amp;quot;&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Массив&lt;br /&gt;
!style=&amp;quot;background-color:#EEE&amp;quot;| Описание шага&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 5 3 4 1 2&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из исходного массива &lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Первый проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 3 4 1 '''5'''&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и последний элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''4''' 3 2 1 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из первых четырёх элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Второй проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''1''' 3 2 '''4''' 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и четвёртый элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''3''' 1 2 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из первых трёх элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Третий проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 1 '''3''' 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и третий элементы &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2''' 1 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Строим кучу из двух элементов&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Четвёртый проход''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''1''' '''2''' 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Меняем местами первый и второй элементы  &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 1 2 3 4 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Массив отсортирован&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
= JSort =&lt;br /&gt;
'''JSort''' является модификацией сортировки кучей, которую придумал Джейсон Моррисон (''Jason Morrison'').&lt;br /&gt;
Алгоритм частично упорядочивает массив, строя на нём два раза кучу: один раз передвигая меньшие элементы влево, второй раз передвигая большие элементы вправо. Затем к массиву применяется&lt;br /&gt;
[[Сортировка вставками|сортировка вставками]], которая при почти отсортированных данных работает за &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Достоинства:&lt;br /&gt;
*В отличие от сортировки кучей, на почти отсортированных массивах работает быстрее, чем на случайных.&lt;br /&gt;
*В силу использования сортировки вставками, которая просматривает элементы последовательно, использование кэша гораздо эффективнее.&lt;br /&gt;
Недостатки:&lt;br /&gt;
*На длинных массивах, возникают плохо отсортированные последовательности в середине массива, что приводит к ухудшению работы сортировки вставками.&lt;br /&gt;
 &lt;br /&gt;
=== Алгоритм ===&lt;br /&gt;
Построим кучу для минимума на этом массиве. &lt;br /&gt;
Тогда наименьший элемент окажется на первой позиции, а левая часть массива окажется почти отсортированной, так как ей будут соответствовать верхние узлы кучи.&lt;br /&gt;
Теперь построим на этом же массиве кучу так, чтобы немного упорядочить правую часть массива. Эта куча должна быть кучей для максимума и быть &amp;quot;зеркальной&amp;quot; к массиву, то есть чтобы её корень соответствовал последнему элементу массива.&lt;br /&gt;
К получившемуся массиву применим сортировку вставками.&lt;br /&gt;
&lt;br /&gt;
=== Сложность ===&lt;br /&gt;
&lt;br /&gt;
Построение кучи занимает &amp;lt;tex&amp;gt;O(n)&amp;lt;/tex&amp;gt;. Почти упорядоченный массив сортировка вставками может отсортировать &amp;lt;tex&amp;gt; O(n)&amp;lt;/tex&amp;gt;, но в худшем случае за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Таким образом, наихудшая оценка Jsort {{---}} &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Пример ===&lt;br /&gt;
Рассмотрим, массив &amp;lt;tex&amp;gt; A &amp;lt;/tex&amp;gt; = &amp;lt;tex&amp;gt; [1, 2, 8, 15, 17, 20, 31, 32, 30, 2, 3, 5, 10, 11, 24 ] &amp;lt;/tex&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Построим на этом массиве кучу для минимума:&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: left; margin-right: left;&amp;quot;&lt;br /&gt;
| [[Файл:HeapW.png|400px]] &lt;br /&gt;
|}&lt;br /&gt;
Массив выглядит следующим образом:&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: left; margin-right: left;&amp;quot;&lt;br /&gt;
| [[Файл:HeapM.png|400px]] &lt;br /&gt;
|}&lt;br /&gt;
Заметим, что начало почти упорядочено, что хорошо скажется на использовании сортировки вставками.&lt;br /&gt;
&lt;br /&gt;
Построим теперь зеркальную кучу для максимума на этом же массиве.&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: left; margin-right: left;&amp;quot;&lt;br /&gt;
| [[Файл:HeapWU.png|400px]] &lt;br /&gt;
|}&lt;br /&gt;
Массив будет выглядеть следующим образом:&lt;br /&gt;
{| cellpadding=&amp;quot;3&amp;quot; style=&amp;quot;margin-left: left; margin-right: left;&amp;quot;&lt;br /&gt;
| [[Файл:HeapMU.png|400px]] &lt;br /&gt;
|}&lt;br /&gt;
Теперь и конец массива выглядит упорядоченным, применим сортировку вставками и получим отсортированный массив.&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Сортировка слиянием]]&lt;br /&gt;
* [[Быстрая сортировка]]&lt;br /&gt;
* [[Теорема о нижней оценке для сортировки сравнениями]]&lt;br /&gt;
&lt;br /&gt;
== Источники информации ==&lt;br /&gt;
* Кормен Т., Лейзерсон Ч., Ривест Р., Штайн К. Алгоритмы: построение и анализ, 2-е издание. Издательский дом &amp;quot;Вильямс&amp;quot;, 2005. ISBN 5-8459-0857-4&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Heapsort Wikipedia {{---}} Heapsort]&lt;br /&gt;
*[http://en.wikipedia.org/wiki/JSort  Wikipedia {{---}} JSort]&lt;br /&gt;
*[http://habrahabr.ru/post/221095/ Хабрахабр {{---}} Описание сортировки кучей и JSort]&lt;br /&gt;
*[https://ru.wikipedia.org/wiki/Пирамидальная_сортировка Википедия {{---}} Пирамидальная сортировка]&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Сортировки]]&lt;/div&gt;</summary>
		<author><name>95.58.179.186</name></author>	</entry>

	</feed>