В основе алгоритмов сортировки «слиянием» лежит объединение двух упорядоченных последовательностей в одну. Это похоже на перестройку двух колон учеников, выстроенных за ростом, в одну. Ученики, первые в своих колонах, сравниваются; вышей становится в новую колонну, другой остается первым в своей. После этого в колонне, из которой пошел ученик, следующий за ростом учений становится первым. Снова сравниваются первые, и так они действуют, пока в одной из колон никого не останется — тогда сдача другой колонны перейдет в хвост новой без изменения порядка.

Пусть в массиве А з элемента A [L ] начинается упорядоченный участок длиной m-L + 1, а из элемента А [га+1] — участок длиной R-m. Под упорядоченным участком (отрезком или серией) понимаем участок, который не является частью другого упорядоченного участка. Например, длина таких упорядоченных участков равняется m-L + 1 = 3 и R-m = 3.

  • из
  • L         m         m+1     R
  • Они объединяются в такой участок длиной R-L+1 во вспомогательном массиве В.
  • 13
  • L         m         m+1     R
  • Рассмотрим процедуру слияния в массив Z пары сопредельных участков массива X, в котором левая содержит индексы от L до т, а права — відт+1 flo.
  • procedure  merge(var   X,Z:aInt;   L,m,R:word); var   k:word;    {индекс   в целевом  массиве} и, j:-word;   {индексы  в половинах) begin
  • и:=L;   j:=т+1; for   k: =L   to   R  do
  • {заполнение элементов Z[L], …, Z[R]) if и>m then
  • begin Z[k]:=X[j]; inc(j) end else if j>r then
  • begin Z[k]:=X[i], inc(i) end
  • Сортировка линейных массивов
  • else   if   X[i]<X[j]    then
  • begin   Z[k]:=X[i];   inc(i)    end else  begin   Z[k]:=X[j];   inc(j)   end end;
  • Очевидно, тело цикла выполняется R — L + І раз, и каждый раз выполняется 0(1) элементарных действий. Итак, сложность выполнения вызова процедуры merge есть &(R-L + l).

Алгоритм сортировки слиянием заключается в повторении таких шагов слияния пар. В массиве происходит поиск пары сопредельных упорядоченных участков, которые объединяются в один участок вспомогательного массива, например, с помощью процедуры merge. Потом происходит поиск и объединяется следующая пара и т.п.. Возможно, в конце останется участок, который не имеет пары, — ее будет скопировано без перемен. На следующем шаге происходит подобное слияние пар участков вспомогательного массива в основной. Шаги повторяются, пока какой-либо из массивов не превратится на один упорядоченный участок. Если это вспомогательный массив, он копируется в основной. Продемонстрируем выполнение алгоритма на массиве А = < 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1> длиной п = 11.

Упорядоченные последовательности выделены дужками < >, пары участков, которые объединяются, отделенные «;», В— имя вспомогательного массива.

  • А = «11Х10>; <9><8>; <7><6>; <5><4>; <3><2>; <1»
  • В= «10, 11X8, 9>; <6, 7X4, 5>; <2, 3><1»
  • Л = «8, 9, 10, 11X4, 5, 6, 7>;<1,2, С»
  • Я = «4, 5,6, 7, 8, 9, 10, 11X1,2,3»
  • Л = <1,2, 3, 4, 5,6, 7, 8, 9, 10, 11>

Как видим, массив отсортирован за четыре шага слияния.

После первого шага слияния длина упорядоченных участков не меньше 2 (за исключением, возможно, «хвоста» длиной 1), после второго — не меньше 4 (кроме, возможно, «хвоста» меньшей длины) и т.п.. Итак, после /-го шага длина упорядоченных участков, кроме, возможно, «хвоста», не меньше 2′. Пусть п — количество элементов массива. На последнему, к-му, шаге объединяются две участка; первая из них имеет длину не меньше 24″1, причем 2*»1 < г.  Итак, количество шагов к < log« + l. За счет возможного дополнительного копирования количество шагов надо увеличить на 1, но оценка 0(logn) сохранится. На каждом шаге общее количество элементарных действий есть 0(и), поэтому сложность алгоритма — 0(и • log п).

Реализуем алгоритм сортировки слиянием с помощью процедуры sortByMrg. Шаг слияния участков одного массива в другого оформим функцией mergeStep. Она возвращает признак того, что на шаге слияния было найдено хотя бы одну пару упорядоченных участков. Если пара не найдено, то массив, начальный в вызове функции, отсортировано. На непарных шагах слияния функция mergeStep выполняет слияние участков основного массива А у вспомогательный массив В, на парных — наоборот. Якшо массив, начальный в вызове mergeStep, оказался отсортированным на парном шаге слияния, значит, это массив В, и его надо скопировать в основной массив А, А если на непарном шаге, то это массив А, и больше ничего делать не надо.

Пара сопредельных упорядоченных участков и-елементного массива (первый из них начинается индексом left) ищет функция findPair. Она возвращает признак того, что пар найден. Правые границы участков сохраняются в ее параметрах mid и right. Если после ее вызова исполняется условие (lef t=l) and (right=n), то пара не найдено, т.е. массив отсортирован. Для слияния используем процедуру merge (см. выше). Вспомогательная процедура копирования участка массива в другой массив copy Аг есть очевидной.

  • procedure copyAr<var X,r:alnt;
  • left,right:word)); var и:word; begin
  • for i:= left to right do Y[i]:= X[i] end; function findPair(var X:alnt; n,left:word;
  • var mid, right   word): boolean; {функция возвращает признак «того, что пара сопредельных упорядоченные участки найдены} begin
  • findPair := false; if left <= n then
  • Сортировка линейных массивов
  • begin
  • mid := left;
  • while (mid<n)and(X[mid]<=X[mid+1]) do
  • inc(mid); {(mid=n) or (X[mid]>X[mid+l])} if mid~n    {правая граница — конец массива} then right:=mid else
  • begin {поиск правой границы} findPair := true; right := mid+1; while(right<n)and(X[right]<=X [right+1])
  • do inc(right); {(right=n) or (X[right]>X[right+l]} end; end; end;
  • function mergeStep(var X,Y:aInt; n.word): boolean;
  • {функция возвращает признак того, что слияние массива X в массив Y состоялось} var left,mid,right:word; begin
  • mergestep:=true; left:=l;
  • while findPair(X,n,left,mid,right) do begin merge(X,Y,left,mid,right) ; left:=right+l end;
  • {последний вызов findPair возвратил false} if (left=l)and(right=n)
  • then mergeStep:=false {массив X отсортировано} else if left<=n
  • then copyAr(X,Y,left,n); {копирование «хвоста»} end;
  • procedure sortByMrg(var A:alnt; n:word); var B:alnt;    {вспомогательный массив}

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

Основной язык сайта

Share
Published by
Основной язык сайта

Recent Posts

Three Factors to Consider When Choosing a Leading Term Papers US Service

If you're looking to earn the best possible grade on your research paper, you need…

12 месяцев ago

How to Write My Essay

To write my essay, first you need to think of the major topic of your…

1 год ago

Term Paper Writing Services

Writing term paper is not a simple endeavor. It involves huge efforts, that need to…

1 год ago

Purchase Term Papers and Books Online

It's possible to purchase term papers and textbooks on the internet at a discount price,…

2 года ago

Essay Topic — Important Ideas to Write Essays

The main reason essay writing is so powerful is because it's a general subject and…

2 года ago

The Best Research Paper Available — Try These Tips

A couple of years ago I received an email from a student asking for information…

2 года ago