<?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=77.232.147.80&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=77.232.147.80&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/77.232.147.80"/>
		<updated>2026-04-05T01:24:15Z</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%B2%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B0%D0%BC%D0%B8&amp;diff=72611</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%B2%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B0%D0%BC%D0%B8&amp;diff=72611"/>
				<updated>2020-02-09T14:43:33Z</updated>
		
		<summary type="html">&lt;p&gt;77.232.147.80: исправлена опечатка &amp;quot;на на&amp;quot; -&amp;gt; &amp;quot;на&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Сортировка вставками''' (англ. ''Insertion sort'') — квадратичный алгоритм [[Сортировка|сортировки]].&lt;br /&gt;
&lt;br /&gt;
==Алгоритм==&lt;br /&gt;
Задача заключается в следующем: есть часть массива, которая уже отсортирована, и требуется вставить остальные элементы массива в отсортированную часть, сохранив при этом упорядоченность. Для этого на каждом шаге алгоритма мы выбираем один из элементов входных данных и вставляем его на нужную позицию в уже отсортированной части массива, до тех пор пока весь набор входных данных не будет отсортирован. Метод выбора очередного элемента из исходного массива произволен, однако обычно (и с целью получения устойчивого алгоритма сортировки), элементы вставляются по порядку их появления во входном массиве.&lt;br /&gt;
&lt;br /&gt;
Так как в процессе работы алгоритма могут меняться местами только соседние элементы, каждый обмен уменьшает число [[Таблица инверсий|инверсий]] на единицу. Следовательно, количество обменов равно количеству инверсий в исходном массиве вне зависимости от реализации сортировки. Максимальное количество инверсий содержится в массиве, элементы которого отсортированы по невозрастанию. Число инверсий в таком массиве &amp;lt;tex&amp;gt;\displaystyle \frac {n(n - 1)} {2}&amp;lt;/tex&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм работает за &amp;lt;tex&amp;gt;O(n + k)&amp;lt;/tex&amp;gt;, где &amp;lt;tex&amp;gt;k&amp;lt;/tex&amp;gt; — число обменов элементов входного массива, равное числу инверсий. В среднем и в худшем случае — за &amp;lt;tex&amp;gt;O(n^2)&amp;lt;/tex&amp;gt;. Минимальные оценки встречаются в случае уже упорядоченной исходной последовательности элементов, наихудшие — когда они расположены в обратном порядке.&lt;br /&gt;
&lt;br /&gt;
==Псевдокод==&lt;br /&gt;
 '''function''' insertionSort(a):&lt;br /&gt;
   '''for''' i = 1 '''to''' n - 1&lt;br /&gt;
     j = i - 1&lt;br /&gt;
     '''while''' j &amp;lt;tex&amp;gt;  \geqslant &amp;lt;/tex&amp;gt; 0 '''and''' a[j] &amp;gt; a[j + 1] &lt;br /&gt;
       swap(a[j], a[j + 1])&lt;br /&gt;
       j--&lt;br /&gt;
&lt;br /&gt;
==Пример работы==&lt;br /&gt;
Пример работы алгоритма для массива &amp;lt;tex&amp;gt;[ 5, 2, 4, 3, 1 ]&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;
!style=&amp;quot;background-color:#EEE&amp;quot;| Описание шага&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Первый проход (проталкиваем второй элемент — '''''2''''')''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''5 2''' 4 3 1&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2 5''' 4 3 1&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Алгоритм сравнивает второй элемент с первым и меняет их местами.&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Второй проход (проталкиваем третий элемент — '''''4''''')''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 2 '''5 4''' 3 1 &lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 2 '''4 5''' 3 1&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 4''' 5 3 1&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2 4''' 5 3 1&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Второй и первый отсортированы, swap не требуется&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Третий проход (проталкиваем четвертый — '''''3''''')''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 2 4 '''5 3''' 1&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 2 4 '''3 5''' 1&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 '''4 3''' 5 1&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 2 '''3 4''' 5 1&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 3''' 4 5 1&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| '''2 3''' 4 5 1&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Второй и первый отсортированы, swap не требуется&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Четвертый проход (проталкиваем пятый элемент — '''''1''''')''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 2 3 4 '''5 1'''&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;| 2 3 '''4 1''' 5&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 2 3 '''1 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 '''3 1''' 4 5&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;| '''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;
Теперь вместо линейного поиска позиции мы будем использовать [[Целочисленный двоичный поиск | бинарный поиск]], следовательно количество сравнений изменится с &amp;lt;tex&amp;gt;O(N^2)&amp;lt;/tex&amp;gt; до &amp;lt;tex&amp;gt; O(N\log N) &amp;lt;/tex&amp;gt;. Количество сравнений заметно уменьшилось, но для того, чтобы поставить элемент на своё место, всё ещё необходимо переместить большое количество элементов. В итоге время выполнения алгоритма в асимптотически не уменьшилось. Бинарные вставки выгодно использовать только в случае когда сравнение занимает много времени по сравнению со сдвигом. Например когда мы используем массив длинных чисел. &lt;br /&gt;
 '''function''' insertionSort(a):&lt;br /&gt;
   '''for''' i = 1 '''to''' n - 1&lt;br /&gt;
     j = i - 1&lt;br /&gt;
     k = binSearch(a, a[i], 0, j)&lt;br /&gt;
     '''for''' m = j '''downto''' k&lt;br /&gt;
       swap(a[m], a[m+1])&lt;br /&gt;
&lt;br /&gt;
=== Двухпутевые вставки ===&lt;br /&gt;
Суть этого метода в том, что вместо отсортированной части массива мы используем область вывода. Первый элемент помещается в середину области вывода, а место для последующих элементов освобождается путём сдвига элементов влево или вправо туда, куда выгоднее.&lt;br /&gt;
Пример для набора элементов &amp;lt;tex&amp;gt;[ 5, 7, 3, 4, 6 ]&amp;lt;/tex&amp;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;
!style=&amp;quot;background-color:#EEE&amp;quot;| Описание шага&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Первый проход (проталкиваем первый элемент — '''''5''''')''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| &lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 30px&amp;quot;| '''5'''&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Так как в поле вывода нет элементов, то мы просто добавляем элемент туда.&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Второй проход (проталкиваем второй элемент — '''''7''''')''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 30px&amp;quot;| 5 &lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 30px&amp;quot;| 5 '''7'''&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| С помощью Бинарного поиска находим позицию и, так как позиция крайняя, то сдвигать ничего не приходится.&lt;br /&gt;
|-  &lt;br /&gt;
|colspan=3|''Третий проход (проталкиваем третий — '''''3''''')''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 30px&amp;quot;| 5 7&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 20px&amp;quot;| '''3''' 5 7&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| С помощью Бинарного поиска находим позицию и, так как позиция крайняя, то сдвигать ничего не приходится.&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Четвертый проход (проталкиваем четвертый элемент — '''''4''''')''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 20px&amp;quot;| 3 5 7&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 3 '''4''' 5 7&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| С помощью Бинарного поиска находим позицию. Расстояние до левого края зоны вывода меньше, чем до правого, значит сдвигаем левую часть.&lt;br /&gt;
|-&lt;br /&gt;
|colspan=3|''Четвертый проход (проталкиваем пятый элемент — '''''6''''')''&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 3 4 5 7&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| 3 4 5 '''6''' 7&lt;br /&gt;
|style=&amp;quot;background-color:#FFF;padding:2px 10px&amp;quot;| Расстояние до правого края меньше чем до левого, следовательно двигаем правую часть.&lt;br /&gt;
|}    &lt;br /&gt;
Как можно заметить структура поля вывода имеет сходство с [[Персистентный дек| деком]], а именно мы выбираем край к которому ближе наш элемент, затем добавляем с этой стороны наш элемент и двигаем его. Как мы видим в этом примере понадобилось сдвинуть всего &amp;lt;tex&amp;gt;3&amp;lt;/tex&amp;gt; элемента. Благодаря тому что для вставки &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;-ого элемента потребуется &amp;lt;tex&amp;gt;j/2&amp;lt;/tex&amp;gt; сдвигов в худшем случае вместо &amp;lt;tex&amp;gt;j&amp;lt;/tex&amp;gt;, то и итоговое число необходимых операций в худшем случае составит &amp;lt;tex&amp;gt;N^2 / 4 + N \log 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;
* [http://ru.wikipedia.org/wiki/%D0%A1%D0%BE%D1%80%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B2%D1%81%D1%82%D0%B0%D0%B2%D0%BA%D0%B0%D0%BC%D0%B8 Сортировка вставками]&lt;br /&gt;
* Н. Вирт '''Алгоритмы и структуры данных''' {{---}} Невский Диалект, 2008. {{---}} 352 с. {{---}} ISBN 978-5-7940-0065-8&lt;br /&gt;
* [http://rain.ifmo.ru/cat/view.php/vis/sorts/quadratic-2010 Визуализатор квадратичных алгоритмов]&lt;br /&gt;
* [http://rain.ifmo.ru/cat/data/theory/school/ses-VectSort-03/pres.pdf Презентация «Сортировка вектора - 3. Insertion Sort»]&lt;br /&gt;
[[Категория: Дискретная математика и алгоритмы]]&lt;br /&gt;
[[Категория: Сортировки]]&lt;br /&gt;
[[Категория: Квадратичные сортировки]]&lt;/div&gt;</summary>
		<author><name>77.232.147.80</name></author>	</entry>

	</feed>