Алгоритмы сортировки: пузырёк, выбор, вставки, быстрая

Алгоритмы сортировки: пузырёк, выбор, вставки, быстрая

Данные на октябрь 2026, Python 3.13Опубликовано 29 августа 2025Обновлено 22 августа 20269 мин чтения
Робот-манипулятор переставляет деревянные кубики разной высоты в ряду
Коротко
  • Алгоритм сортировки расставляет элементы списка в заданном порядке, например по возрастанию.
  • Пузырёк, выбор и вставки делают порядка n² сравнений, быстрая сортировка в среднем — порядка n·log n.
  • Устойчивая сортировка не меняет порядок элементов с одинаковыми ключами.
  • На практике в Python используют встроенную sorted: она устойчива и работает по алгоритму Timsort.
Содержание12 разделов ▾
  1. Зачем сортировать и что такое устойчивость
  2. Сортировка пузырьком
  3. Сортировка выбором
  4. Сортировка вставками
  5. Быстрая сортировка
  6. Сортировка слиянием
  7. Сколько это стоит
  8. Встроенная сортировка Python
  9. Как выбрать алгоритм
  10. Условия и ограничения
  11. Частые ошибки
  12. Короткий вывод

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

Описания алгоритмов сверены с Википедией и учебником Седжвика и Уэйна, поведение встроенной сортировки — с документацией Python. Код проверен запуском на Python 3.13. Данные на октябрь 2026 года.

Зачем сортировать и что такое устойчивость

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

Устойчивость заметна, когда в списке есть записи с равными ключами. Например, люди с одинаковым годом рождения: устойчивая сортировка по году оставит их в прежнем порядке.

Сортировка пузырьком

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

Википедия называет пузырёк простейшим для понимания и реализации и отмечает, что он эффективен для массивов небольшого размера. В худшем и среднем случаях он делает порядка n² операций, в лучшем — порядка n.

Python
def пузырёк(данные):
    a = list(данные)
    for проход in range(len(a) - 1):
        обмен = False
        for i in range(len(a) - 1 - проход):
            if меньше(a[i + 1], a[i]):
                a[i], a[i + 1] = a[i + 1], a[i]
                обмен = True
        if not обмен:          # обменов не было — список уже упорядочен
            break
    return a

Функцию меньше мы определим в полном примере ниже: она сравнивает два элемента и считает сравнения.

Сортировка выбором

Идея: находим наименьший элемент среди ещё не упорядоченных и ставим его на первое место, затем ищем наименьший среди оставшихся и ставим на второе. Википедия отмечает, что в худшем, среднем и лучшем случаях выбор делает порядка n² операций. Даже на уже отсортированном списке он делает те же сравнения.

Python
def выбор(данные):
    a = list(данные)
    for i in range(len(a) - 1):
        мин = i
        for j in range(i + 1, len(a)):
            if меньше(a[j], a[мин]):
                мин = j
        a[i], a[мин] = a[мин], a[i]
    return a

Сортировка вставками

Идея: так раскладывают карты в руке. Берём очередной элемент и вставляем его на нужное место среди уже упорядоченных слева. По Седжвику и Уэйну, на случайных данных вставки делают в среднем около N²/4 сравнений, в худшем случае около N²/2, а в лучшем — N−1. Метод хорошо работает на данных, которые уже почти упорядочены.

Python
def вставки(данные):
    a = list(данные)
    for i in range(1, len(a)):
        x = a[i]
        j = i - 1
        while j >= 0 and меньше(x, a[j]):
            a[j + 1] = a[j]
            j -= 1
        a[j + 1] = x
    return a

Быстрая сортировка

Идея «разделяй и властвуй»: выбираем опорный элемент, делим остальные на меньшие и большие, затем рекурсивно сортируем обе части. Седжвик и Уэйн пишут, что это самый широко используемый алгоритм сортировки. В среднем он делает порядка 2N·ln N сравнений, а в худшем случае порядка N²/2; случайное перемешивание перед сортировкой защищает от худшего случая.

Python
def быстрая(данные):
    if len(данные) <= 1:
        return list(данные)
    опорный = данные[len(данные) // 2]
    меньшие, равные, большие = [], [], []
    for x in данные:
        if меньше(x, опорный):
            меньшие.append(x)
        elif меньше(опорный, x):
            большие.append(x)
        else:
            равные.append(x)
    return быстрая(меньшие) + равные + быстрая(большие)

Эта версия учебная: она создаёт новые списки, поэтому тратит память. Версии, которые работают на месте, быстрее, но сложнее.

Сортировка слиянием

Идея: делим список пополам, сортируем каждую половину, затем сливаем две упорядоченные половины в один список. По Википедии, сортировка слиянием делает порядка n·log n операций во всех случаях, а по Седжвику и Уэйну гарантирует такое время. Она устойчива. Цена за это — дополнительная память для массива. Код мы не приводим: для обзора достаточно таблицы ниже.

Сколько это стоит

Запустим четыре алгоритма на одном и том же случайном списке и посчитаем сравнения. Список составлен из случайных чисел с фиксированным зерном, поэтому вывод повторяется.

Python
import random

сравнений = 0

def меньше(a, b):
    """Сравнивает два элемента и считает сравнения."""
    global сравнений
    сравнений += 1
    return a < b

алгоритмы = [("пузырёк", пузырёк), ("выбор", выбор), ("вставки", вставки), ("быстрая", быстрая)]

random.seed(1)
print("размер  алгоритм  сравнений")
for размер in (100, 1000):
    данные = [random.randint(0, 10_000) for _ in range(размер)]
    for имя, f in алгоритмы:
        сравнений = 0
        результат = f(данные)
        assert результат == sorted(данные)
        print(f"{размер:>6}  {имя:<8}  {сравнений:>9}")

Функции пузырёк, выбор, вставки и быстрая из разделов выше нужно поместить в тот же файл перед этим кодом. Вывод при запуске на Python 3.13:

Текст
размер  алгоритм  сравнений
   100  пузырёк        4905
   100  выбор          4950
   100  вставки        2327
   100  быстрая        1049
  1000  пузырёк      499464
  1000  выбор        499500
  1000  вставки      245727
  1000  быстрая       17356

При росте списка в 10 раз сравнений у пузырька стало больше почти в 100 раз, а у быстрой сортировки примерно в 16. Выбор делает ровно n(n−1)/2 сравнений: 4950 для 100 элементов и 499 500 для 1000. Вставки на случайных данных дали около четверти от n², что совпадает с оценкой N²/4 из учебника. Быстрая сортировка в нашей версии делает два сравнения на элемент (меньше и больше опорного), поэтому цифры у неё чуть выше теоретических.

АлгоритмЛучший случайВ среднемХудший случайДополнительная памятьУстойчивость
Пузырькомnn²n²O(1)устойчив
Выборомn²n²n²O(1)неустойчив (стандартная реализация)
Вставкамиnn²n²O(1)устойчив
Быстраяn·log nn·log nn²от O(log n) до O(n)неустойчива
Слияниемn·log nn·log nn·log nO(n) для массиваустойчива

Значения взяты из карточек алгоритмов в Википедии и из перечня устойчивых и неустойчивых сортировок на странице «Алгоритм сортировки». Оценки показывают рост при увеличении размера списка, а не время в секундах.

Встроенная сортировка Python

На практике Python используют не самописную сортировку, а встроенную. Документация описывает две возможности: функция sorted возвращает новый отсортированный список, а метод list.sort меняет список на месте. Параметр key задаёт ключ, а reverse=True — обратный порядок. Документация гарантирует, что сортировка устойчива: записи с одинаковым ключом сохраняют исходный порядок. Алгоритм — Timsort, который использует упорядоченность, уже имеющуюся в данных.

Python
люди = [("Анна", 1990), ("Борис", 1985), ("Вера", 1990), ("Глеб", 1985)]

# Встроенная сортировка Python устойчива: у равных годов порядок имён сохраняется
print(sorted(люди, key=lambda p: p[1]))

# list.sort сортирует на месте, sorted возвращает новый список
числа = [5, 2, 9, 1]
новый = sorted(числа, reverse=True)
числа.sort()
print(новый, числа)
Текст
[('Борис', 1985), ('Глеб', 1985), ('Анна', 1990), ('Вера', 1990)]
[9, 5, 2, 1] [1, 2, 5, 9]

Внутри каждого года порядок имён сохранился: Борис перед Глебом, Анна перед Верой. Так же было в исходном списке.

Как выбрать алгоритм

СитуацияПодходящий метод
Учебная задача, список небольшойлюбой простой: пузырёк, выбор, вставки
Список почти упорядоченвставки: в лучшем случае порядка n сравнений
Нужна устойчивость и гарантированное n·log nслиянием
Большой случайный список, устойчивость не нужнабыстрая сортировка
Рабочий код на Pythonвстроенная sorted или list.sort

Условия и ограничения

Версия
Python 3.13, октябрь 2026 — код проверен запуском; число сравнений у случайных списков зависит от зерна генератора.
Язык
Примеры на Python — в C и C++ реализация отличается, но идея алгоритмов та же.
Данные
Учебные списки — списки из 100 и 1000 чисел показывают рост, но не заменяют измерений на реальных данных.
Сложность
Рост, а не секунды — оценка O(…) описывает, как растёт число операций, а не время работы в секундах.
Устойчивость
Не у всех алгоритмов — быстрая сортировка и выбор в стандартной реализации неустойчивы.

Частые ошибки

  • Берут пузырёк для больших списков: число сравнений растёт как квадрат размера.
  • Путают сложность и время в секундах: O(n²) говорит о росте, а не о конкретной скорости.
  • Не учитывают устойчивость, когда сортируют по нескольким признакам подряд.
  • Пишут свою сортировку вместо встроенной sorted в рабочем коде.
  • Берут первый элемент опорным в быстрой сортировке на уже упорядоченных данных и получают худший случай.
  • Забывают, что list.sort меняет список на месте и возвращает None, а sorted возвращает новый список.

Короткий вывод

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

Источники

  1. Python Docs: Sorting Techniques↗ docs.python.org
  2. Sedgewick, Wayne. Algorithms, 4th ed.: 2. Sorting↗ algs4.cs.princeton.edu
  3. Sedgewick, Wayne: 2.1 Elementary Sorts↗ algs4.cs.princeton.edu
  4. Sedgewick, Wayne: 2.3 Quicksort↗ algs4.cs.princeton.edu
  5. Яндекс Образование: Основы алгоритмов (хендбук)↗ education.yandex.ru
  6. Википедия: Алгоритм сортировки↗ ru.wikipedia.org
  7. Википедия: Сортировка пузырьком↗ ru.wikipedia.org
  8. Википедия: Сортировка выбором↗ ru.wikipedia.org
  9. Википедия: Сортировка вставками↗ ru.wikipedia.org
  10. Википедия: Быстрая сортировка↗ ru.wikipedia.org
  11. Википедия: Сортировка слиянием↗ ru.wikipedia.org
  12. Википедия: Устойчивая сортировка↗ ru.wikipedia.org

Частые вопросы

Какие бывают алгоритмы сортировки?

Самые известные — сортировка пузырьком, выбором, вставками, слиянием, быстрая и пирамидальная. Википедия делит их на устойчивые (пузырьком, вставками, слиянием) и неустойчивые (выбором, быстрая, пирамидальная). Пузырёк, выбор и вставки делают порядка n² сравнений, слияние и быстрая сортировка — порядка n·log n. Для обучения начинают с простых, на практике берут встроенные средства языка.

Чем быстрая сортировка лучше пузырька?

Быстрая сортировка в среднем делает порядка n·log n сравнений, а пузырьковая — порядка n². При размере списка 1000 элементов в нашем эксперименте на Python пузырёк сделал около 499 тысяч сравнений, а быстрая сортировка — около 17 тысяч. Разница растёт вместе с размером списка. Но быстрая сортировка в худшем случае тоже может делать порядка n² сравнений, поэтому опорный элемент выбирают осторожно.

Что такое устойчивая сортировка?

Устойчивая сортировка не меняет взаимного расположения элементов с одинаковыми ключами. Если два человека родились в одном году и в исходном списке Анна стояла перед Верой, то после устойчивой сортировки по году Анна по-прежнему будет перед Верой. Это важно при сортировке по нескольким признакам: сначала по одному, затем по другому. Документация Python гарантирует, что встроенные сортировки устойчивы.

Какой алгоритм сортировки использует Python?

Встроенные sorted и list.sort используют алгоритм Timsort. Документация Python упоминает его и отмечает, что он эффективно использует упорядоченность, уже имеющуюся в данных. Википедия описывает Timsort как гибрид сортировок вставками и слиянием. Встроенная сортировка устойчива, поэтому на практике пишите sorted(данные) или данные.sort(), а свои реализации оставляйте для обучения и особых случаев.

Где бесплатно изучать алгоритмы на русском?

Подойдёт хендбук «Основы алгоритмов» на платформе Яндекс Образования. Он рассказывает об алгоритмах без привязки к языкам программирования, а в разделах есть структуры данных, графы, жадные алгоритмы, динамическое программирование и техника «разделяй и властвуй». По описанию авторов, достаточно школьных знаний по информатике и логике. Для основ также есть русскоязычные статьи Википедии об отдельных сортировках.

РедакцияМатериал подготовлен по источникам выше · 22 августа 2026