Сортировка слиянием — различия между версиями
Кирилл (обсуждение | вклад) |
Кирилл (обсуждение | вклад) |
||
Строка 15: | Строка 15: | ||
=Слияние 2-х массивов= | =Слияние 2-х массивов= | ||
Допустим, у нас есть два отсортированных массива А и B размерами <tex>N_a </tex> и <tex>N_b </tex> соответственно, и мы хотим объединить их элементы в один большой отсортированный массив C размером <tex>N_a + N_b </tex> . Для этого можно применить процедуру слияния, суть которой заключается в повторяющемся «отделении» элемента, наименьшего из двух имеющихся в началах исходных массивов, и присоединении этого элемента к концу результирующего массива. Элементы мы переносим до тех пор, пока один из исходных массивов не закончится. После этого оставшийся «хвост» одного из входных массивов дописывается в конец результирующего массива. Пример работы процедуры показан на рисунке: | Допустим, у нас есть два отсортированных массива А и B размерами <tex>N_a </tex> и <tex>N_b </tex> соответственно, и мы хотим объединить их элементы в один большой отсортированный массив C размером <tex>N_a + N_b </tex> . Для этого можно применить процедуру слияния, суть которой заключается в повторяющемся «отделении» элемента, наименьшего из двух имеющихся в началах исходных массивов, и присоединении этого элемента к концу результирующего массива. Элементы мы переносим до тех пор, пока один из исходных массивов не закончится. После этого оставшийся «хвост» одного из входных массивов дописывается в конец результирующего массива. Пример работы процедуры показан на рисунке: | ||
− | [[Файл:Mergearr.png|center| | + | [[Файл:Mergearr.png|center|500px|thumb|Пример работы процедуры слияния.]] |
<br> | <br> | ||
Алгоритм слияния формально можно записать следующим образом: | Алгоритм слияния формально можно записать следующим образом: | ||
Строка 45: | Строка 45: | ||
Merge fragments (a,c) and (c + 1,b); | Merge fragments (a,c) and (c + 1,b); | ||
End | End | ||
+ | |||
+ | |||
+ | Время работы сортировки слиянием составляет <tex>O(n * ln(n))</tex>. Пример работы процедуры показан на рисунке: | ||
+ | [[Файл:Merge sort1.png|500px|center|thumb|Пример работы рекурсивного алгоритма сортировки слиянием]] |
Версия 01:23, 16 мая 2011
Сортировка слиянием
Сортировка слиянием — вероятно, один из самых простых алгоритмов сортировки (среди «быстрых» алгоритмов).Сортировка слиянием — стабильный алгоритм сортировки. Это означает, что порядок «равных» элементов не изменяется в результате работы алгоритма. В некоторых задачах это свойство достаточно важно. Этот алгоритм был предложен Джоном фон Нейманом в 1945 году.
Принцип работы
Эта сортировка — хороший пример использования принципа «разделяй и властвуй». Сначала задача разбивается на несколько подзадач меньшего размера. Затем эти задачи решаются с помощью рекурсивного вызова или непосредственно, если их размер достаточно мал. Наконец, их решения комбинируются, и получается решение исходной задачи.
Для решения задачи сортировки эти три этапа выглядят так:
- Сортируемый массив разбивается на две части примерно одинакового размера;
- Каждая из получившихся частей сортируется отдельно, например — тем же самым алгоритмом;
- Два упорядоченных массива половинного размера соединяются в один.
Рекурсивное разбиение задачи на меньшие происходит до тех пор, пока размер массива не достигнет единицы
(любой массив длины 1 можно считать упорядоченным).
Слияние 2-х массивов
Допустим, у нас есть два отсортированных массива А и B размерами
и соответственно, и мы хотим объединить их элементы в один большой отсортированный массив C размером . Для этого можно применить процедуру слияния, суть которой заключается в повторяющемся «отделении» элемента, наименьшего из двух имеющихся в началах исходных массивов, и присоединении этого элемента к концу результирующего массива. Элементы мы переносим до тех пор, пока один из исходных массивов не закончится. После этого оставшийся «хвост» одного из входных массивов дописывается в конец результирующего массива. Пример работы процедуры показан на рисунке:
Алгоритм слияния формально можно записать следующим образом:
a = 0; b = 0; While (a <) and (b < ) If A[a] B[b] C[a + b] = A[a]; a = a + 1; Else C[a + b] = B[b]; b = b + 1; End; End; If a < Copy remain part of A Else Copy remain part of B End;
Рекурсивный алгоритм
Проще всего формализовать этот алгоритм рекурсивным способом. Функция сортирует участок массива от элемента с номером a до элемента с номером b:
Function MergeSort(a,b) If b = a then Exit; c = (a + b)/2; Mergesort(a,c); MergeSort(c + 1,b); Merge fragments (a,c) and (c + 1,b); End
Время работы сортировки слиянием составляет . Пример работы процедуры показан на рисунке: