Сортировки выбором, вставками и пузырьком — три простейшие сортировки. Все работают за и дополнительной памяти.
Зачем нужно
Это первые алгоритмы сортировки курса: просто написать, просто доказать, на них хорошо видна устойчивость. Общий недостаток — квадратичное время.
Как работает
Во всех трёх for i = 0 ... N означает полуинтервал , а swap —
обмен двух элементов через временную переменную.
Выбором (Selection Sort)
Первые позиций уже заняты наименьшими элементами по порядку. В остатке ищем минимум и ставим его на позицию .
for i = 0 ... N
for j = i ... N
если arr[i] > arr[j]
swap(arr[i], arr[j])Неустойчива: — обмен через весь массив перебрасывает через .
Вставками (Insertion Sort)
Левая часть отсортирована. Очередной элемент «проваливается» влево, пока левый сосед больше его.
for i = 0 ... N
j = i + 1
while (j > 0 и arr[j] < arr[j−1])
swap(arr[j], arr[j−1])
j = j − 1Так на доске — с выходом за массив
При получается
j = N, иwhileчитаетarr[N]. Внешний цикл должен идти доN − 1. Подробно — в конспекте L03.
Устойчива: обмен только при строгом <, через равный элемент не
перепрыгивают.
Пузырьком (Bubble Sort)
Проход по соседним парам «всплывает» максимум вправо. После проходов последние позиций на месте.
for i = 0 ... N
for j = 0 ... N−i−1
если arr[j] > arr[j+1]
swap(arr[j], arr[j+1])Устойчива: меняются только соседи и только при строгом >.
Сводка
| Устойчива | |||
|---|---|---|---|
| Выбором | нет | ||
| Вставками | да | ||
| Пузырьком | да |
Не из лекции: инварианты
- Выбор: перед шагом в
arr[0..i)лежат наименьших элементов по порядку. Внутренний цикл сохраняет «вarr[i]минимум просмотренного».- Вставки: перед шагом отсортирован префикс
arr[0..i]. Вставка останавливается, когда слева не больше, а справа — то, через что элемент прошёл, всё больше его.- Пузырёк: во время прохода в
arr[j+1]лежит максимумarr[0..j+1]; после прохода последние позиций — наибольшие элементы по порядку.Полные доказательства — в конспекте L03.
Не из лекции: сравнения и инверсии
Инверсия (inversion) — пара позиций с
arr[p] > arr[q]. Обмен соседей, стоящих не по порядку, убирает ровно одну инверсию. Поэтому у вставок и пузырька обменов ровно столько, сколько инверсий, — от 0 до .
Сравнений Выбором на любом входе Вставками от (отсортирован) до (по убыванию) Пузырьком на любом входе Прогон на : выбор — 500 500 сравнений; вставки — 999 на отсортированном массиве и 499 500 на обратном; пузырёк — 499 500. Вставки — единственная из трёх, которая на почти отсортированном массиве работает почти линейно.
Тонкости
- Сортировка выбором на доске делает
swapпри каждом найденном меньшем элементе. Классический вариант запоминает индекс минимума и делает один обмен за шаг. Оценка та же, неустойчивы оба. - Устойчивость вставок и пузырька держится на строгом сравнении. С
≤(или≥) они остаются правильными, но перестают быть устойчивыми. - У пузырька последний проход пустой.
Частые ошибки
- Выход за границу:
arr[j+1]приj = N − 1в пузырьке илиarr[N]во вставках с доски. swapбез временной переменной: послеa = bстарое значениеaпотеряно.- Считать, что раз у всех трёх , они одинаково быстры. На почти отсортированных данных вставки работают почти линейно, а выбор и пузырёк — нет.
Углубление — АиСД L04
Лекция начинается с итога: у всех трёх , и при это операций — при операций в секунду около секунд, почти три часа. Это повод для сортировки слиянием за — на том же входе около 0,2 секунды.