Сортировка выбором
Сортировка выбором — один из базовых алгоритмов сортировки. Она проста для понимания и реализации. Главное правило: на каждом проходе выбирается элемент с экстремальным значением (максимум или минимум) в оставшейся неотсортированной части и ставится на своё место в отсортованной части.
Что делает алгоритм пошагово
Возьмём пример списка: [39, 82, 2, 51, 30, 42, 7]. Допустим, мы сортируем по возрастанию, ставя на каждую итерацию наибольший элемент в конец остающейся части.
- Первый проход: находим наибольшее число во всём массиве — 82. Меняем местами с элементом в последней позиции (7). Список становится: [39, 7, 2, 51, 30, 42, 82]. Теперь правая часть (последний элемент) считается отсортированной.
- Второй проход: ищем максимум в оставшихся элементах [39, 7, 2, 51, 30, 42] — это 51. Меняем его с последним элементом в этой части (42). Список: [39, 7, 2, 42, 30, 51, 82].
- Повторяем, пока не получим полностью отсортированный массив.
Во время работы алгоритм поддерживает две области: отсортованную (обычно справа или слева) и неотсортованную. Каждая итерация сокращает неотсортированную область на один элемент.
Визуализация показывает, какие элементы в каждый момент считаются максимумом и какие уже перенесены в отсортированную часть.
Алгоритм и псевдокод
Существует два распространённых варианта: искать максимум и заполнять конец массива, или искать минимум и заполнять начало. Оба дают одинаковую асимптотику и похожую стоимость операций обмена.
Код-реализации, как в исходном примере, приведён ниже.
Python:
def selectionSort(mylist):
for x in range(len(mylist) - 1, 0, -1):
max_idx = 0
for posn in range(1, x + 1):
if mylist[posn] > mylist[max_idx]:
max_idx = posn
temp = mylist[x]
mylist[x] = mylist[max_idx]
mylist[max_idx] = tempJava:
void selectionSort(int my_array[]){
for (int x = 0; x < my_array.length - 1; x++)
{
int index = x;
for (int y = x + 1; y < my_array.length; y++){
if (my_array[y] < my_array[index]){
index = y; // find lowest index
}
}
int temp = my_array[index]; // temp is a temporary storage
my_array[index] = my_array[x];
my_array[x] = temp;
}}Код выше корректно демонстрирует идею: один внешний цикл и вложенный цикл поиска экстремума, затем обмен.
Анализ сложности
- Сравнения: на первом проходе делается (n-1) сравнений, на втором (n-2), и так далее. Сумма — примерно n(n-1)/2 сравнений. Это даёт временную сложность O(n²).
- Перестановки (swap): максимум n-1 обменов, то есть O(n) по количеству перестановок.
- Память: алгоритм in-place — дополнительная память O(1).
Важно: O(n²) — квадратичная сложность, не экспоненциальная. Для больших n время работы растёт быстро.
Когда сортировка выбором подходит, а когда нет
Подходит:
- Учёба и объяснение базовых идей сортировки.
- Маленькие массивы или когда число обменов критично (количество обменов у selection sort минимально среди простых алгоритмов, т.к. делает до n-1 swap).
- Сценарии с очень дорогими операциями записи, где нужно минимизировать количество перестановок.
Не подходит:
- Большие объёмы данных — квадратичная скорость становится узким местом.
- Когда важна устойчивость сортировки (selection sort нестабилен: равные элементы могут поменять порядок).
Альтернативы и переход к более быстрым алгоритмам
Если важна скорость на больших данных, рассмотрите:
- Сортировка слиянием (merge sort): O(n log n), стабильна, требует O(n) доп. памяти.
- Быстрая сортировка (quick sort): среднее O(n log n), in-place, но в худшем O(n²).
- Сортировка вставками (insertion sort): эффективна на почти отсортированных массивах; O(n²) в общем случае.
Совет: для общего применения в стандартных библиотеках используют гибриды и более оптимизированные алгоритмы с гарантией O(n log n).
Практические рекомендации и чек-листы
Чек-лист для разработчика перед выбором selection sort:
- Размер массива < 100–1000? Тогда можно использовать для простоты и читаемости.
- Нужна ли стабильность? Если да — этот алгоритм не подойдёт.
- Критично ли число обменов? Если да — selection sort может быть предпочтительнее insertion sort.
Чек-лист для ревьюера кода:
- Алгоритм in-place и не использует лишнюю память? Проверить.
- Правильны ли границы циклов (off-by-one ошибки)?
- Корректно ли выполняются сравнения для выбора min/max?
Роль студента: понять идею, написать реализацию и проанализировать сложность. Роль инженера: выбрать алгоритм под задачи и протестировать на граничных случаях.
Тесты и критерии приёмки
Критерии приёмки:
- Алгоритм корректно сортирует случайные массивы разных длин.
- Работает с дубликатами и отрицательными числами.
- Не использует больше памяти, чем O(1) дополнительной.
- Количество обменов ≤ n-1 для массива длины n.
Минимальные тестовые случаи:
- Пустой массив и массив из одного элемента.
- Уже отсортированный массив.
- Обратный порядок.
- Массив с повторяющимися элементами.
Ментальные модели и когда ожидаемо провалит
- Модель «разделяй на отсортенную и неотсортованную части»: на каждой итерации один элемент переходит в отсортованную область.
- Провалит на больших n из-за квадратичной сложности. Ожидайте медленную работу при n в десятки тысяч и выше.
Факто-бокс
- Временная сложность: O(n²) в среднем и в худшем случае.
- Число обменов: максимум n-1.
- Память: O(1).
- Стабильность: нестабилен.
Опытные инженеры отмечают: для понимания основ алгоритмов сортировка выбором — хороший учебный пример, но в продакшене её используют редко.
Заключение
Сортировка выбором проста и наглядна. Она полезна для обучения и в узких практических случаях, где критично число обменов или размер массива мал. Для производительных систем предпочтительнее алгоритмы с O(n log n).
Копируйте или используйте приведённый код как шаблон, но при переходе к реальным большим данным заменяйте selection sort на более эффективный метод.
Краткое резюме: Сортировка выбором — понятная, in-place, но квадратичная. Выбирайте её для обучения и небольших задач; для больших данных используйте merge sort или quick sort.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone