Сортировка слиянием - это алгоритм сортировки, который работает, разделяя заданный список пополам, рекурсивно сортируя оба меньших списка и объединяя их обратно в один отсортированный список. Базовый случай рекурсии приходит к одноэлементному списку, который не может быть разделен далее, но по определению уже отсортирован.
Выполнение алгоритма в списке [1,7,6,3,3,2,5]
можно визуализировать следующим образом:
[1,7,6,3,3,2,5]
/ \ split
[1,7,6,3] [3,2,5]
/ \ / \ split
[1,7] [6,3] [3,2] [5]
/ \ / \ / \ | split
[1] [7] [6] [3] [3] [2] [5]
\ / \ / \ / | merge
[1,7] [3,6] [2,3] [5]
\ / \ / merge
[1,3,6,7] [2,3,5]
\ / merge
[1,2,3,3,5,6,7]
Задание
Напишите программу или функцию, которая принимает список целых чисел любым разумным способом в качестве входных данных и визуализирует различные разделы этого списка, сортируя их с помощью алгоритма сортировки слиянием. Это означает, что вам не нужно выводить график, как указано выше, но только списки в порядке:
[1,7,6,3,3,2,5]
[1,7,6,3][3,2,5]
[1,7][6,3][3,2][5]
[1][7][6][3][3][2][5]
[1,7][3,6][2,3][5]
[1,3,6,7][2,3,5]
[1,2,3,3,5,6,7]
Кроме того, любая разумная нотация списка подходит, поэтому следующие данные также могут быть действительными:
1 7 6 3 3 2 5
1 7 6 3|3 2 5
1 7|6 3|3 2|5
1|7|6|3|3|2|5
1 7|3 6|2 3|5
1 3 6 7|2 3 5
1 2 3 3 5 6 7
Наконец, способ разбить список на два меньших списка зависит от вас, если длина обоих результирующих списков отличается не более чем на один. Это означает, что вместо разделения [3,2,4,3,7]
на [3,2,4]
и [3,7]
вы также можете разделять, беря элементы по четным и нечетным индексам ( [3,4,7]
и [2,3]
) или даже случайным образом разбивая разделение каждый раз.
Это код-гольф , поэтому выигрывает самый короткий код на любом языке, измеряемый в байтах.
Контрольные примеры
Как отмечалось выше, фактический формат и способ разделения списков пополам зависит от вас.
[10,2]
[10][2]
[2,10]
[4,17,1,32]
[4,17][1,32]
[4][17][1][32]
[4,17][1,32]
[1,4,17,32]
[6,5,4,3,2,1]
[6,5,4][3,2,1]
[6,5][4][3,2][1]
[6][5][4][3][2][1]
[5,6][4][2,3][1] <- Important: This step cannot be [5,6][3,4][1,2], because 3 and 4 are on different branches in the the tree
[4,5,6][1,2,3]
[1,2,3,4,5,6]
[[1,2],[3],[4,5],[6]]
Этап на самом деле является правильным решением, так как сортировка слиянием работает рекурсивно. То есть, если мы начнем с [1,2,3,4,5,6]
и разделим его на [1,2,3]
и [4,5,6]
, то эти списки будут обрабатываться независимо, пока они не будут объединены на последнем этапе.
[3]
и [2,1]
, то они находятся в разных ветвях, поэтому мы не можем объединиться, [3]
а [2]
после [2,1]
делим на [2]
и [1]
.