Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция по информатике №13.doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
121.86 Кб
Скачать

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

Принцип сортировки поясняется следующим примером.

Пусть дан массив

5

9

4

6

1

8

7

3

В первой фазе сортировки массив делится пополам, половинки удобно считать расположенными одна над другой

5

9

4

6

1

8

7

3

Производится слияние (с сортировкой) одиночных чисел, расположенных одно над другим. Из этих пар вновь составляется один общий массив

1

5

8

9

4

7

3

6

который состоит из подряд идущих упорядоченных пар.

В второй фазе сортировки массив вновь делится пополам, половинки удобно считать расположенными одна над другой

1

5

8

9

4

7

3

6

Производится слияние (с сортировкой) теперь уже пар чисел, расположенных одна над другой. Из этих четверок вновь составляется один общий массив

1

4

5

7

3

6

8

9

который состоит из подряд идущих упорядоченных четверок.

Длина упорядоченных фрагментов растет «в геометрической прогрессии» и за короткое число фаз достигает длины всего массива.

Ниже приведен полный текст процедуры StraightMergeSort – процедуры сортировки прямым слиянием.

procedure StraightMergeSort;

var

i,j,k,L,t,h,m,p,q,r:

integer;

bUp:

boolean;

begin

nMove:=0;

nCompare:=0;

bUp:=true;

p:=1;

repeat

h:=1;

m:=nCurr;

if bUp then

begin i:=1; j:=nCurr; k:=nCurr+1; L:=2*nCurr; end

else

begin k:=1; L:=nCurr; i:=nCurr+1; j:=2*nCurr; end;

repeat

if m>=p then q:=p else q:=m;

m:=m-q;

if m>=p then r:=p else r:=m;

m:=m-r;

while (q<>0) and (r<>0) do

begin

nCompare:=nCompare+1;

if A[i]<A[j] then

begin

A[k]:=A[i];

i:=i+1; q:=q-1;

end

else

begin

A[k]:=A[j];

j:=j-1; r:=r-1;

end;

nMove:=nMove+2;

k:=k+h;

end;

while r>0 do

begin

A[k]:=A[j];

nMove:=nMove+2;

k:=k+h; j:=j-1; r:=r-1;

end;

while q>0 do

begin

A[k]:=A[i];

nMove:=nMove+2;

k:=k+h; i:=i+1; q:=q-1;

end;

h:=-h; t:=k; k:=L; L:=t;

until m=0;

bUp:=not bUp;

p:=2*p;

until p>=nCurr;

if not bUp then

for i:=1 to nCurr do

begin

A[i]:=A[i+nCurr];

// nMove:=nMove+2;

end;

end;

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

Идея сортировки состоит в следующем.

Сортируемый массив из элементов разбивается на подмассивы, каждый из которых «случайно» оказался отсортированным. Пусть имеется в виду сортировка по возрастанию Тогда правая граница подмассива – это индекс элемента массива, который является последним или после которого возрастание «вдруг» сменяется убыванием.

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

Даже если массив не упорядочивался частично, вероятность, что все отсортированные подмассивы состоят из одного элемента, достаточно мала.

Слушателям предлагается самостоятельно оценить, чему именно равна такая вероятность.

Пример.

Исходный массив:

3 5 16 18 1 13 17 2 9 11 4 12 7 10 15

Поиск упорядоченных подмассивов и их слияние (по два)

Ниже приведен полный текст процедуры NaturalMergeSort – процедуры сортировки слиянием.

procedure NaturalMergeSort;

var

i, nB: integer;

mB: array[0..2] of integer;

bBound, bSorted: boolean;

procedure Merge(p, q, r: integer);

var

i, j, k: integer;

begin

i:=p;

j:=q+1;

k:=n;

while (i<=q) and (j<=r) do

begin

Inc(k);

Inc(nC);

if A[i]<A[j] then

begin

A[k]:=A[i];

Inc(i);

end

else

begin

A[k]:=A[j];

Inc(j);

end;

Inc(nM);

end;

while i<=q do

begin

Inc(k);

A[k]:=A[i];

Inc(nM);

Inc(i);

end;

while j<=r do

begin

Inc(k);

A[k]:=A[j];

Inc(nM);

Inc(j);

end;

k:=n;

for i:=p to r do

begin

Inc(k);

A[i]:=A[k];

end;

end;

begin

while True do

begin

nB:=0;

mB[0]:=1;

bSorted:=True;

for i:=1 to n do

begin

bBound:=False;

if i=n then

bBound:=True

else

if A[i]>A[i+1] then

begin

bBound:=True;

bSorted:=False;

end;

if bBound then

begin

Inc(nB);

mB[nB]:=i;

end;

if nB=2 then

begin

Merge(mB[0], mB[1], mB[2]);

nB:=0;

mB[0]:=mB[2];

end;

end;

if bSorted then Break;

end;

end;