Menu
Coddy logo textTech

Merge Sort

Последнее обновление

Сортировка слиянием - это алгоритм по принципу «разделяй и властвуй». Он рекурсивно делит массив пополам, пока в каждой части не останется один элемент (который тривиально отсортирован), а затем сливает части обратно в правильном порядке. Шаг слияния проходит по двум отсортированным подмассивам двумя указателями, всегда копируя следующим меньший передний элемент. Нажмите «воспроизвести» выше, чтобы увидеть, как массив пересобирается слияние за слиянием.

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

Временная и пространственная сложность

СлучайСложностьПримечания
Лучший случайO(n log n)Всегда делит вход пополам
Средний случайO(n log n)Случайный порядок
Худший случайO(n log n)Гарантировано - плохих входов нет
ПамятьO(n)Временный буфер для слияния
СтабильнаДаНичьи при слиянии разрешаются в пользу левой части

Шаг за шагом

ШагЧто происходит
1Если в диапазоне 0 или 1 элемент, он уже отсортирован.
2Разделите диапазон на две половины.
3Рекурсивно отсортируйте левую половину сортировкой слиянием.
4Рекурсивно отсортируйте правую половину сортировкой слиянием.
5Слейте две отсортированные половины двумя указателями.

Разобранный пример

Сортировка [5, 2, 4, 1]:

ПроходМассивДействие
Разделить[5, 2] | [4, 1]Разделите массив на две половины
Разделить[5] [2] | [4] [1]Делите снова, пока каждая часть не станет одним элементом
Слить[2, 5] | [1, 4]Слейте [5],[2] в [2, 5] и [4],[1] в [1, 4]
Слить[1, 2, 4, 5]Слейте [2, 5] и [1, 4]: выберите 1, затем 2, затем 4, затем 5
Готово[1, 2, 4, 5]Массив полностью отсортирован

Когда использовать сортировку слиянием

Используйте, когдаИзбегайте, когда
Нужен гарантированный худший случай O(n log n)Памяти мало, и O(n) дополнительного пространства недопустимо
Важна стабильность (равные ключи сохраняют порядок)Вы сортируете небольшие массивы, где сортировка вставками быстрее
Вы сортируете связный списокСортировка на месте - жёсткое требование
Данные слишком велики для ОЗУ (внешняя сортировка)Доминирует локальность кэша, и проходы quicksort на месте выигрывают

Код Merge Sort

Чистая, готовая к запуску реализация Merge Sort на Python, JavaScript, Java, C++, C. Выберите язык, скопируйте код или откройте его уже загруженным в плейграунде Coddy.

Код Merge Sort на Python

Python
1def merge_sort(a):2    if len(a) <= 1:3        return a4    mid = len(a) // 25    left = merge_sort(a[:mid])6    right = merge_sort(a[mid:])7    return merge(left, right)8
9
10def merge(left, right):11    out = []12    i = j = 013    while i < len(left) and j < len(right):14        if left[i] <= right[j]:15            out.append(left[i])16            i += 117        else:18            out.append(right[j])19            j += 120    out.extend(left[i:])21    out.extend(right[j:])22    return out23
24
25nums = [38, 27, 43, 3, 9, 82, 10]26print("Before:", nums)27print("After: ", merge_sort(nums))
Запустите этот код в плейграунде Python

Часто задаваемые вопросы о сортировке слиянием

Какова временная сложность сортировки слиянием?
Сортировка слиянием - это O(n log n) в лучшем, среднем и худшем случаях, потому что она всегда делит массив пополам. Она использует O(n) дополнительной памяти под буфер слияния.
Стабильна ли сортировка слиянием?
Да, когда шаг слияния разрешает ничьи, беря сначала из левой половины. Это сохраняет равные элементы в их исходном относительном порядке, поэтому сортировка слиянием - распространённый выбор для стабильной сортировки.
Почему использовать сортировку слиянием вместо quicksort?
Сортировка слиянием гарантирует O(n log n) даже на враждебных входах и стабильна, тогда как quicksort может деградировать до O(n²). Сортировку слиянием также предпочитают для связных списков и внешней сортировки. Недостаток - O(n) дополнительной памяти.
В чём разница между сортировкой слиянием и quicksort?
Обе - сортировки по принципу «разделяй и властвуй», но quicksort разбивает вокруг опорного элемента и сортирует на месте с O(log n) памяти стека, а сортировка слиянием слепо делит пополам и сливает с помощью буфера O(n). Quicksort обычно быстрее на практике из-за локальности кэша, но сортировка слиянием имеет гарантированный худший случай O(n log n) и стабильна.
Когда стоит использовать сортировку слиянием на практике?
Выбирайте сортировку слиянием, когда нужна стабильная сортировка с гарантированной границей O(n log n), при сортировке связных списков (где не нужен произвольный доступ) или при внешней сортировке данных, слишком больших для памяти. Избегайте её при нехватке памяти, так как она требует O(n) дополнительного места.
Сортирует ли сортировка слиянием на месте?
Нет. Стандартная сортировка слиянием выделяет временный буфер O(n) для слияния двух половин, поэтому она не на месте. Существуют варианты слияния на месте, но они сложны и либо медленнее, либо теряют стабильность, поэтому версия с буфером - распространённый выбор.
Coddy programming languages illustration

Освойте алгоритмы с Coddy

НАЧАТЬ