Алгоритм сортировки вставкой (Insertion Sort): принцип работы

Модуль "Сортировки" • урок 2 из 17 •

Также упоминается как: Метод простой вставки, Сортировка вставками, Сортировка включением

Суть урока. Вставка (Insertion) поэлементно строит отсортированную часть слева, вставляя каждый следующий элемент на подходящее место (со сдвигом бо́льших вправо). Устойчива, O(N²), но на почти отсортированных данных дает O(N).

Это самый интуитивно понятный алгоритм. Именно так большинство людей сортируют карты в руках при игре: берут новую карту и вставляют ее в правильное место среди уже отсортированных.

Идея метода сортировки

Алгоритм сортировки вставкой: пошаговое перемещение ключа
Сортировка вставкой: выбор очередного ключа, пошаговый сдвиг больших элементов вправо и фиксация элемента на нужной позиции.

В тренажере можно по шагам проследить, как работает сортировка вставкой: берем следующий элемент и ищем ему место в уже отсортированной части.

Тренажер: алгоритм сортировки вставкой

Отсортируем массив 3 6 4 5 1 7 вставкой.

еще не разобрана вставляемый ключ готовая часть слева
Сравнения: 0 Сдвиги: 0 Шаг: 0 / 0
_↓_
Insertion Sort
Сортировка вставками
Берем элементы по одному и вставляем их в правильное место отсортированной части массива. Отлично работает на почти отсортированных данных.
Разобрать по шагам в большой версии →
Сравнение с 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.

Проверьте себя

Как поведет себя сортировка вставкой, если на вход подать массив, который уже почти отсортирован по возрастанию?

Как вам урок? Спасибо за отзыв!