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

Сортировка слиянием (англ. merge sort)[1] является простым, но эффективным алгоритмом сортировки, который также как и алгоритм быстрой сортировки построен по принципу «разделяй и властвуй», однако реализует его несколько по-другому. Массив делится пополам, левая и правая половина рекурсивно сортируется тем же методом слияния, затем отсортированные части объединяются в один отсортированный массив. В соответствии с алгоритмом деление продолжается до части массива, состоящего из одного элемента. Такой массив сразу является отсортированным, поэтому задача сводится к написанию метода, который выполняет слияния двух отсортированных частей массива в один.

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


Задача 6.7 Напишите рекурсивный метод сортировки слиянием целочисленного массива.

Объяснение: в программеиспользуются следующие методы:

mergeSort(int[] arr) – выполняет сортировку массива arr[], вызывая для этого метод mergeSort(int[] arr, int low, int high, int[] buff);

mergeSort(int[] arr, int low, int high, int[] buff) – выполняет сортировку массива arr[] от индекса low до индекса high. В качестве аргумента в метод передается вспомогательный буфер buff[]. Метод осуществляет рекурсивное деление массива пополам и вызов метода слияния merge().

merge(int[]arr, int low, int high, int mid, int[] buff) – метод выполняет слияние отсортированных частей массива: левой от идекса low до mid и правой от индекса mid+1 до индекса high.

Пример выполнения алгоритма сортировки слиянием массива {5, 0, -10, 9, 15, 100, -12, 3} иллюстрирует рис. 6.5.

public class MergeSort {

static void mergeSort(int[] arr) {

mergeSort(arr, 0, arr.length - 1, new int[arr.length]);

}

static void mergeSort(int[] arr, int low, int high, int[] buff){

//Выполняем разделение

if (low >= high) {

return;

}

int mid = (low + high)/2;

mergeSort(arr, low, mid, buff);

mergeSort(arr, mid+1, high, buff);

//Вызываем метод слияния

merge(arr,low, high, mid, buff);

}

static void merge(int[]arr, int low, int high, int mid, int[] buff)

{

int left = low, right = mid + 1;

//Выполняем слияние

for (int i = low; i <= high; i++) {

if (right>high||left<=mid && arr[left]<=arr[right])

{

buff[i] = arr[left++];

} else {

buff[i] = arr[right++];

}

}

//Копируем буфер в массив arr

for (int i = low; i <= high; i++) {

arr[i] = buff[i];

}

}

public static void main(String[]args) {

int[] a = {5,0,-10,9,15,100,-12,3};

mergeSort(a);

System.out.println(java.util.Arrays.toString(a));

}}

Результат:

 
 

[-12, -10, 0, 3, 5, 9, 15, 100]

Сортировка слиянием является одним из самых простых алгоритмов сортировки среди быстрых алгоритмов, который может быть эффективно использован для сортировки связанных списков. Недостаток алгоритма заключается в том, что он требует дополнительную память размером порядка n, и не гарантирует сохранение порядка элементов с одинаковыми значениями. Его временная сложность всегда пропорциональна .

Рис.6.6 – Демонстрация выполнения алгоритма сортировки слиянием


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: