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

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

Также упоминается как: Линейный выбор с обменом, Сортировка выбором

Суть урока. Выборка (Selection) на каждом шаге находит минимум в правой (неотсортированной) части и одним обменом ставит его на свое место. Неустойчива, строго O(N²), но делает минимальное количество обменов (≤ N).

Этот алгоритм тоже предельно прост: мы ищем самый маленький элемент в массиве и меняем его местами с первым. Затем ищем самый маленький из оставшихся и ставим на второе место, и так далее.

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

Алгоритм сортировки выборкой: поиск минимума и обмен
Сортировка выборкой: линейный поиск наименьшего элемента в неотсортированном остатке массива и его обмен с первым неотсортированным элементом.

Интерактивная схема ниже покажет, как сортировка выборкой раз за разом ищет минимум и ставит его на свое место.

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

Отсортируем массив 5 2 6 1 4 3 выборкой минимума.

хвост сканируем текущий минимум готовая часть
Сравнения: 0 Обмены: 0 Шаг: 0 / 0
_v_
Selection Sort
Сортировка выбором
Находим самый маленький элемент в неотсортированной части и ставим его на правильное место. Минимум обменов.
Разобрать по шагам в большой версии →
O-O
Cycle Sort
Циклическая сортировка
Теоретический предел минимизации записей: разбивает массив на циклы перестановок и помещает каждый элемент сразу в его финальную позицию.
Разобрать по шагам в большой версии →

В отличие от сортировки вставкой, выборка всегда работает за строгое время O(N²), даже если массив уже идеально отсортирован. Но у нее есть уникальный плюс: она делает минимальное количество обменов в памяти (всего O(N)), что бывает полезно, когда запись на диск или в память очень дорогая.

Реализация на языке C

void SelectionSort(int arr[], int n) {
    int i, j, min_idx;

    // Двигаем границу неотсортированной части
    for (i = 0; i < n - 1; i++) {
        min_idx = i; // Предполагаем, что первый элемент - минимальный

        // Ищем реальный минимум в оставшейся правой части
        for (j = i + 1; j < n; j++) {
            if (arr[j] < arr[min_idx]) {
                min_idx = j;
            }
        }

        // Делаем ОДИН обмен - ставим найденный минимум на место i
        if (min_idx != i) {
            Swap(&arr[min_idx], &arr[i]);
        }
    }
}

Сравнение алгоритмов

  • Вставка (Insertion): Лучшее время O(N), среднее/худшее O(N²). Строго устойчива. Отличный выбор для малых или почти отсортированных данных. Работает сдвигами.
  • Выборка (Selection): Строго O(N²) во всех случаях. По умолчанию неустойчива. Делает линейное количество обменов (O(N)).

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

Какой из алгоритмов делает строго не более N обменов (записей в память) при сортировке?

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