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

Лекция 13 Сортировка массивов (продолжение) Шейкерная сортировка

Данная сортировка есть улучшенный вариант сортировки методом пузырька.

На первом полушаге проверяются (справа налево) все пары соседних элементов массива, начиная с последней. Если пара «неправильная» (левый элемент больше правого), производится обмен значениями в паре. Наименьший из всех элементов массива, если только он не стоял на первом месте, «просочится» в результате первого шага на первую позицию, поскольку он будет «неправильно» расположен относительно каждого из своих соседей слева. Вместе с тем, может оказаться и так, что первый элемент изначально был минимальным. Более того, может оказаться так, что первые k элементов изначально занимали подобающие им места, поскольку были наименьшими и стояли в порядке возрастания. Признаком такой ситуации может послужить то, что первые k элементов не участвовали в обмене. Следовательно, последующая сортировка должна затронуть только элементы массива с номерами большими, чем k. Переменная L (после изменения оператором L:=k+1) имеет смысл левой границы неотсортированной пока части массива.

На втором полушаге проверяются (теперь слева направо) все пары соседних элементов массива, начиная с (L-1)–ой. Если последние k элементов изначально занимали подобающие им места, поскольку были наибольшими и стояли в порядке возрастания, переменная R (после изменения оператором R:=k-1) будет содержать информацию о правой границе неотсортированной пока части массива.

На втором и последующем шагах продолжают сближаться левая и правая границы неотсортированной части массива. Когда они «схлестнутся», сортировка заканчивается.

Шейкерная сортировка, увы, работает несколько хуже сортировки методом прямого выбора.

procedure ShakerSort;

var

j,k,L,R: integer;

x,y: single;

begin

nMove:=0;

nCompare:=0;

L:=2; R:=nCurr; k:=nCurr;

repeat

for j:=R downto L do

begin

x:=A[j-1]; y:=A[j];

nMove:=nMove+2;

nCompare:=nCompare+1;

if x>y then

begin

A[j-1]:=y; A[j]:=x;

k:=j;

nMove:=nMove+2;

end;

end;

L:=k+1;

for j:=L to R do

begin

x:=A[j-1]; y:=A[j];

nMove:=nMove+2;

nCompare:=nCompare+1;

if x>y then

begin

A[j-1]:=y; A[j]:=x;

k:=j;

nMove:=nMove+2;

end;

end;

R:=k-1;

until L>R;

end;

Сортировка Шелла

procedure ShellSort;

var

i, j, k, L, m, nSteps: integer;

x: Single;

mSteps: array of integer;

begin

nSteps := 1;

i := 1;

SetLength(mSteps, nSteps);

mSteps[nSteps - 1] := i;

while true do

begin

i := 3 * i + 1;

if 3 * i >= nCurr then break;

Inc(nSteps);

SetLength(mSteps, nSteps);

mSteps[nSteps - 1] := i;

end;

nCompare := 0;

nMove := 0;

for m := nSteps downto 1 do

begin

k := mSteps[m - 1];

for L := 1 to k do

begin

i := L + k;

while i <= nCurr do

begin

x := A[i];

Inc(nMove);

j := i;

while (j > k) and (x < A[j - k]) do

begin

Inc(nCompare);

A[j] := A[j - k];

Inc(nMove, 2);

j := j - k;

end;

if j > k then Inc(nCompare);

A[j] := x;

Inc(nMove);

i := i + k;

end;

end;

end;

end;