Сортировка слияния в Java
1. Введение
В этом учебнике, мы будем смотреть на алгоритм Merge Sort и его реализация в Java .
Сортировка слияний является одним из наиболее эффективных методов сортировки и основана на парадигме «разделяй и властвуй».
2. Алгоритм
Сортировка слияния — это алгоритм «разделяй и властвуй», в котором мы сначала делим проблему на подпроблемы. Когда решения для подпроблем будут готовы, мы объединим их вместе, чтобы получить окончательное решение проблемы.
Это один из алгоритмов, которые могут быть легко реализованы с помощью рекурсии, как мы имеем дело с subproblems, а не основной проблемой.
Алгоритм можно охарактеризовать как следующий двухшаговой процесс:
- Разделите: На этом этапе мы делим входной массив на две половины , стержень является средней точкой массива. Этот шаг осуществляется повторно для всех полу массивов до тех пор, пока не будет больше половины массивов, чтобы разделить.
- Завоевание: На этом этапе мы сортим и объединяем разделенные массивы снизу вверх и получить отсортированную массив.
На следующей диаграмме показан полный процесс сортировки слияния для массива примеров No10, 6, 8, 5, 7, 3, 4.
Если присмотреться к диаграмме, то увидим, что массив повторяется на две половины до тех пор, пока размер не станет 1. Как только размер становится 1, процессы слияния вступают в действие и начинают слияние массивов обратно во время сортировки:
3. Осуществление
Для реализации, Мы напишем слияниеСорт функция, которая принимает в входном массиве и его длина в качестве параметров. Это будет рекурсивная функция, поэтому нам нужна база и рекурсивные условия.
Базовое условие проверяет, если длина массива 1, и он будет просто вернуться. В остальных случаях будет выполнен рекурсивный вызов.
Для рекурсивного случая мы получаем средний индекс и создаем два временных массива l’ и р-р . слияниеСорт функция затем называется рекурсивно для обоих подразрядов:
public static void mergeSort(int[] a, int n) { if (n < 2) { return; } int mid = n / 2; int[] l = new int[mid]; int[] r = new int[n - mid]; for (int i = 0; i < mid; i++) { l[i] = a[i]; } for (int i = mid; i < n; i++) { r[i - mid] = a[i]; } mergeSort(l, mid); mergeSort(r, n - mid); merge(a, l, r, mid, n - mid); }
Затем мы называем слияние функция, которая принимает входные и как под массивы, так и стартовые и конечные индексы как под массивов, так .
тем сливать функция сравнивает элементы обоих подразрядов один за другим и помещает меньший элемент в входной массив.
Когда мы достигаем конца одного из подразрядов, остальные элементы из другого массива копируются в входной массив, тем самым давая нам окончательный отсортированный массив:
public static void merge( int[] a, int[] l, int[] r, int left, int right) { int i = 0, j = 0, k = 0; while (i < left && j < right) { if (l[i] <= r[j]) { a[k++] = l[i++]; } else { a[k++] = r[j++]; } } while (i < left) { a[k++] = l[i++]; } while (j < right) { a[k++] = r[j++]; } }
Удельный тест для программы:
@Test public void positiveTest() { int[] actual = { 5, 1, 6, 2, 3, 4 }; int[] expected = { 1, 2, 3, 4, 5, 6 }; MergeSort.mergeSort(actual, actual.length); assertArrayEquals(expected, actual); }
4. Сложность
Поскольку сортировка слияния является рекурсивным алгоритмом, сложность времени может быть выражена как следующее рекурсивное отношение:
T(n) = 2T(n/2) + O(n)
2T (n/2) соответствует времени, необходимому для сортировки подразрядов и О(н) время для слияния всего массива.
Когда решается, сложность времени придет к O (nLogn).
Это верно для худшего, среднего и наилучшего случая, поскольку он всегда будет делить массив на две части, а затем объединиться.
Космическая сложность алгоритма О(н) как мы создаем временные массивы в каждом рекурсивном вызове.
5. Заключение
В этом быстром учебнике мы увидели работу алгоритма сортировки слияния и то, как мы можем реализовать его в Java.
Весь рабочий код доступен более на GitHub .