Все темы
36

Сортировка через деление и слияние

Tier 1Закрыто

Где применяется

1. Задача

Сортировки, которые ты писал раньше, проходят по списку снова и снова. На списке из n элементов они делают примерно n на n сравнений. Для 100 элементов это 10 000 сравнений, и это терпимо. Для миллиона это уже триллион. Нужна сортировка, у которой работа растёт гораздо медленнее.

Начнём с простого факта. Два уже отсортированных списка легко объединить в один отсортированный. Смотришь на первые числа обоих списков и берёшь меньшее, и так снова и снова. Значит, если бы у тебя уже были две отсортированные половины, работа была бы почти сделана.

Сортировка слиянием превращает этот факт в полный метод. Раздели список пополам, отсортируй каждую половину, потом слей две отсортированные половины в одну.

Этот шаг из платной части

Бесплатные шаги в начале курса (их 33) открыты всем: урок, задача и тесты. Этот шаг открывается с полным доступом. Начни с бесплатного аккаунта и бесплатных шагов.

Завести бесплатный аккаунтПосмотреть, что входит
Сортировка слиянием: разрезать пополам и слить
mergeSort([5, 2, 4, 6, 1, 3])
arr
5
2
4
6
1
3
left
пусто
right
пусто
out
пусто

Сортируем [5, 2, 4, 6, 1, 3]. Merge sort режет посередине, не глядя на значения, сортирует каждую половину и сливает их.

Гонка скорости
Три сортировки на одних и тех же 40 числах

Одна операция: одно сравнение или одно перемещение. За каждый кадр все дорожки делают одинаковое число операций, поэтому медленная отстаёт.

Сортировка пузырьком O(n²)
операций: 0
Сортировка слиянием O(n log n)
операций: 0
Быстрая сортировка O(n log n)
операций: 0

 

А если чисел больше

Операции для n чисел и примерное время при 100 миллионах простых операций в секунду. Это оценка по тому же счёту, а не замер.

n = 1 000
Сортировка пузырьком749,3 тыс. · 7,5 мс
Сортировка слиянием19,9 тыс. · меньше 1 мс
Быстрая сортировка18,4 тыс. · меньше 1 мс
n = 100 000
Сортировка пузырьком7,5 млрд · 1,2 мин
Сортировка слиянием3,3 млн · 33 мс
Быстрая сортировка3,1 млн · 31 мс
n = 10 000 000
Сортировка пузырьком75 трлн · 8,7 дн.
Сортировка слиянием465,1 млн · 4,7 с
Быстрая сортировка430,2 млн · 4,3 с

Как узнать

Быстрая сортировка (merge / quick) (Fast sort (merge / quick))

Эти слова в условии значат этот паттерн

  • сортировка массива реального размера (тысячи+)
  • нужна гарантированная или ожидаемая O(n log n)
  • сортировка как подготовительный шаг перед другим алгоритмом (два указателя, жадный, сканирующая прямая)
  • нужна стабильность (сортировка слиянием) или сортировка на месте (быстрая сортировка)
  • просто «отсортируй это» без намёка на малое n или особые ключи

Похоже, но не то

n до 1e6 даёт O(n log n). Merge требует O(n) дополнительной памяти, quick требует O(log n).

На LeetCode

Задачи, где нужна сортировка за O(n log n) на любом входе, слияние двух отсортированных списков или подсчёт пар прямо во время слияния. Раздели пополам, отсортируй половины и слей их с начала.

Мы используем необходимые куки для работы сайта (вход и язык). Если ты согласишься, мы также загрузим Google Analytics, чтобы видеть, какие страницы читают, и Google reCAPTCHA для защиты форм обратной связи и сообщений об ошибке от спама. Политика конфиденциальности