Алгоритм сортировки вставкой (Insertion Sort): принцип работы
Также упоминается как: Метод простой вставки, Сортировка вставками, Сортировка включением
Суть урока. Вставка (Insertion) поэлементно строит отсортированную часть слева, вставляя каждый следующий элемент на подходящее место (со сдвигом бо́льших вправо). Устойчива, O(N²), но на почти отсортированных данных дает O(N).
Это самый интуитивно понятный алгоритм. Именно так большинство людей сортируют карты в руках при игре: берут новую карту и вставляют ее в правильное место среди уже отсортированных.
Идея метода сортировки
- Массив условно делится на две части: левую (отсортированную) и правую (неотсортированную). В начале отсортированная часть состоит только из одного первого элемента.
- На каждом шаге берем первый элемент из правой части (назовем его
key). - Последовательно сравниваем
keyс элементами левой части, двигаясь справа налево. Если элементы в левой части больше, они сдвигаются на одну позицию вправо, освобождая место. - Как только находим элемент меньше
key(или достигаем начала массива), вставляем наш элемент в освободившуюся "дырку".
В тренажере можно по шагам проследить, как работает сортировка вставкой: берем следующий элемент и ищем ему место в уже отсортированной части.
Тренажер: алгоритм сортировки вставкой
Отсортируем массив 3 6 4 5 1 7 вставкой.
еще не разобрана
вставляемый ключ
готовая часть слева
Сравнения: 0
Сдвиги: 0
Шаг: 0 / 0
Insertion Sort
Сортировка вставками
Берем элементы по одному и вставляем их в правильное место отсортированной части массива. Отлично работает на почти отсортированных данных.
Разобрать по шагам в большой версии →
Сравнение с Python (Timsort)
Алгоритм O(N²) кажется бесполезным, но в Python он является краеугольным камнем! Встроенный быстрый алгоритм Timsort (используемый в
Алгоритм O(N²) кажется бесполезным, но в Python он является краеугольным камнем! Встроенный быстрый алгоритм Timsort (используемый в
list.sort()) разбивает огромный массив на маленькие части (по 32-64 элемента) и сортирует их именно вставкой. На маленьких и почти отсортированных массивах этот алгоритм работает феноменально быстро, приближаясь к времени O(N) без накладных расходов рекурсии!
Реализация на языке C
void InsertionSort(int arr[], int n) {
int i, key, j;
// Начинаем со второго элемента (индекс 1)
for (i = 1; i < n; i++) {
key = arr[i]; // Запоминаем текущий элемент
j = i - 1;
// Сдвигаем все элементы отсортированной части,
// которые больше key, на одну позицию вправо
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
// Вставляем key на освободившееся место
arr[j + 1] = key;
}
}
Коротко: главное
- Сортировка вставкой поэлементно строит отсортированную часть массива слева.
- На каждом шаге новый элемент вставляется на свое место со сдвигом больших элементов вправо.
- В худшем и среднем случаях алгоритм работает за время O(N²).
- На почти отсортированных массивах время работы приближается к O(N).
- Алгоритм устойчив и используется как часть гибридной сортировки Timsort в Python.
Проверьте себя
Как поведет себя сортировка вставкой, если на вход подать массив, который уже почти отсортирован по возрастанию?
Как вам урок?
Спасибо за отзыв!