Слайд 3
Наименьшее число сравнений появятся, если элементы с самого
начала упорядочены, а наихудшее, если элементы расположены в обратном
порядке, т.е. сортировка простыми включениями демонстрирует естественное поведение, кроме того алгоритм описывает устойчивую сортировку, т.е. оставляет неизменным порядок элементов с одинаковыми ключами
Слайд 4
Алгоритм сортировки простыми включениями можно улучшить тем, что
готовая последовательность a1, a2, …, ai-1 уже упорядочена. Можно
применить бинарный поиск, пока не будет найдено место включения.
Модифицированный алгоритм называется сортировка бинарными включениями.
For i: = 2 to n do
begin
x: = a[i]; L: =1; R: = i-1;
While L<=R do
begin
m: = (L+R) div 2;
If x else L: = m+1
end;
For j: =i-1 downto L do a[j+1]: =a[j];
a[L]: = x;
end;
Слайд 5
Анализ алгоритма сортировки бинарными включениями: места включения в
нижней части находятся несколько быстрее, чем в верхней части.
Это дает преимущество в тех случаях, когда элементы изначально далеки от правильного порядка. Минимальное число сравнений требуется, если элементы вначале расположены в обратном порядке, а максимальное, – если он уже упорядочены. Следовательно, имеем случай неестественного поведения алгоритма сортировки. Улучшение, которое мы получаем, используя метод бинарного поиска, касается только числа сравнений, а ни числа необходимых пересылок. Пересылка требует больше времени, чем сравнение, т.е. это улучшение не является решающим.
Вывод: сортировка включениями является не очень подходящим методом для ЭВМ. Лучших результатов можно ожидать от методов, при которых пересылки элементов выполняются только для отдельных элементов и на большие расстояния.
Слайд 6
Метод основан на следующем правиле:
Выбирается элемент с наименьшим
ключом
Меняется местами с первым элементом.
Эти операции повторяются с оставшимися
n-1 элементами, затем с n-2 и т.д.
44 55 12 42 94 18 06 67
06 55 12 42 94 18 44 67
06 12 55 42 94 18 44 67
06 12 18 42 94 55 44 67
6 12 18 42 94 55 44 67
06 12 18 42 44 55 94 67
06 12 18 42 44 55 94 67
06 12 18 42 44 55 67 94
Слайд 7
Var i, j, k: index; x: item;
begin
For i: = 1 to n-1 do
begin
k: =i; x: = a[i];
For j: =i+1 to n do
If a[j] < x then begin
k: =j;
x: = a[j];
end;
a[k]: = a[i]; a[i]: =x;
end;
end;
Анализ сортировки простым выбором
Число сравнений ключей не зависит от начального порядка ключей. Т.е. сортировка простым выбором ведет себя несколько менее естественно, чем сортировка простыми включениями. Минимальное число пересылок получается в случае изначально упорядоченных ключей и максимальное, – если ключи расположены в обратном порядке.
Слайд 8
Алгоритм основан на принципе сравнения пары соседних элементов
до тех пор, пока не будут отсортированы.
44 06 06 06 06 06 06 06
55 44 12 12 12 12 12 12
12 55 44 18 18 18 18 18
42 12 55 44 42 42 42 42
94 42 18 55 44 44 44 44
18 94 42 42 55 55 55 55
06 18 94 67 67 67 67 67
67 67 67 94 94 94 94 94
Слайд 9
For i: =2 to n do
Begin
For j: = n downto
i do
If a[j-1] > a[j] Then
Begin
x: =a[j-1];
a[j-1]: =a[j];
a[j]: = x
end;
end;
Слайд 10
1)Алгоритм можно оптимизировать (в примере 3 последних прохода
не влияют на порядок элементов). Поэтому можно запомнить производился
ли на данном проходе какой-либо обмен. Если нет, то алгоритм может закончить работу.
2) Можно запоминать не только сам факт обмена, но и индекс последнего обмена, т.к. элементы, которые расположены выше уже рассортированы.
3) 12 18 42 44 55 67 94 06
94 06 12 18 42 44 55 67
Неправильно расположенный пузырек в тяжелом конце массива всплывет на свое место за один проход, а неправильно расположенный пузырек в легком конце массива будет опускаться на правильное место только на один шаг на каждом проходе. Следовательно, предполагается менять, следующих друг за другом проходов.
Слайд 11
Полученный в результате алгоритм называется шейкер- сортировка.
L=2
3
3 4 4
R=8 8 7 7 4
44 06 06 06 06
55 44 44 12 12
12 55 12 44 18
42 12 42 18 42
94 42 55 44 44
18 94 18 55 55
06 18 67 67 67
67 67 94 94 94
Слайд 12
Var i, j, k, L, R: Index; x:
Item;
begin
L: =2; R: =n; k: =n;
repeat
for j: =r downto L do
if a[j-1] > a[j] then begin
x: = a[j-1];
a[j-1]: = a[j];
a[j]: =x; k: =j;
end;
L: =k+1;
for j: =L to R do
if a[j-1] > a[j] then begin
x: = a[j-1];
a[j-1]: = a[j];
a[j]: =x; k: =j;
end ;
R: =k-1;
until L>R;
end;
Слайд 13
Анализ пузырьковой сортировки и шейкер-сортировки.
Все предложенные усовершенствования уменьшают
лишь число избыточных проверок, но никак не влияют на
число обмена. Все усовершенствования дают гораздо меньший эффект, чем можно было ожидать. Анализ показывает, что сортировка обменом и ее небольшие улучшения хуже, чем сортировка включениями и выбором. Алгоритм шейкер- сортировки выгодно использовать в тех случаях, когда известно, что элементы почти упорядочены. Можно показать средне расстояние, на которое должен переместиться каждый из n элементов сортировки. Оно равно n/3.
Все простые методы в основном перемещают каждый элемент на одну позицию на каждом элементарном шаге, поэтому они требуют n2 таких шагов. Любое улучшение должно основываться на принципе пересылки элементов за один шаг на большее расстояние.
Слайд 14
Сортировка включениями с убывающим приращением.
Ее иногда называют
сортировкой Шелла.
44 55 12
42 94 18 06 67 – 4 – сортировка
44 18 06 42 94 55 12 67 – 2 – сортировка
06 18 12 42 44 55 94 67 – 1 – сортировка
06 12 18 42 44 55 67 94
На первом проходе группируются и сортируются все элементы, отстоящие друг от друга на 4 позиции. После этого элементы вновь объединяются в группы с элементами отстоящими друг от друга на 2 позиции и сортируются заново. На третьем проходе элементы сортируются обычной сортировкой.
Слайд 15
На каждом шаге сортировки либо участвует сравнительно мало
элементов, либо они уже довольно хорошо упорядочены и требуют
относительно мало перестановок. Каждый проход использует результаты предыдущего прохода, поскольку каждая i – сортировка объединяет 2 группы, рассматриваемой предыдущей 2i – сортировкой. Применима любая последовательность приращений, лишь бы последнее было равно единице, т.к. в худшем случае вся работа будет выполнена на последнем проходе. Оказывается, что программа дает лучший результат, когда приращения не являются степенями двойки. Программа разрабатывается вне связи с конкретной последовательностью приращений h1,h2,…,ht; ht =1; hi+1 < hi. Каждая h-сортировка программируется как сортировка простыми включениями. Для того чтобы условие окончания поиска места включения было простым, используют барьер, но каждая h- сортировка своего барьера.
Массив a необходимо дополнить не одной компонентой a[0], а h1 компонентами: a:array[-h1..n] of item
Слайд 16
const t=4;
var
i, j, k,
s: index; x: Item;
m: 1..t;
h: array[1..t] of integer;
begin
h[1]=9; h[2]= 5; h[3]=3; h[4]=1;
for m: =1 to t do
begin
k: = h[m]; s: =-k;{место барьера}
for i: =k+1 to n do
begin
x: =a[i]; j: =i-k;
if s=0 Then s: =-k; s: =s+1; a[s]; =x;
while x < a[j] do
begin
a[j+k]: = a[j]; j: =j-k;
end;
a[j+k]: =x;
end;{for…}
end;{for…}
end;
Слайд 17
Анализ сортировки Шелла: основной вопрос в этой сортировке:
какую выбрать последовательность приращений. Например, считается, что эти приращения
не должны быть кратны друг другу, тогда получается лучший результат.
Кнут предлагает:
1, 4, 13, 40, 121 {hk-1=3hk+1}
1, 3, 7, 15, 31 {hk-1=2hk+1}
Анализ показывает, что затраты, которые требуются для сортировки n элементов (Шелла), пропорциональны n. Ясно, что это значительное улучшение по сравнению с предыдущими. Но естm алгоритмы, работающие еще лучше.
Слайд 18
Сортировка с разделением
Иначе ее называют «быстрая сортировка» (сортировка
Хоара). Основана на том факте, что для достижения большей
эффективности желательно производить обмены элементов на больших расстояниях.
Предположим, дано n элементов с ключами, расположенными в обратном порядке. Их можно рассортировать, выполнив n/2 обменов. Поменять местами самый левый и самый правый элементы, постепенно продвигаясь к середине.
Алгоритм
Х
Выберем случайным образом какой-либо элемент массива (X), просмотрим массив, двигаясь слева направо, пока не найдем элемент a[I] > X. А затем просмотрим массив, двигаясь справа налево, пока не найдем элемент a[J] < X и поменяем местами эти два элемента. Затем продолжим процесс просмотра с обменом, пока 2 просмотра не встретятся где-то в середине.
Слайд 19
var w, x: item;
i,
j: integer;
begin
i: =1; j: =n;
{Выбор
случайного элемента }
repeat
while a[i] while x < a[j] do j: =j-1;
if i<= j then begin
w: =a[i]; a[i]: =a[j]; a[j]: =w;
i: =i+1; j: =j-1;
end;
until i>j
end;
44 55 12 42 94
06 18 67
Для такого массива потребуется всего 2 прохода и конечное значение индексов i=5, j=3.
18 06 12 42 94 55 44 67
Алгоритм может быть неуклюжим: массив с n одинаковыми ключами.
Наша цель не только разделить исходный массив на две части большую и меньшую x, но и рассортировать его. Разделив массив надо сделать тоже самое с обеими полученными частями, затем с частями этих частей и т.д., пока каждая часть не будет содержать только один элемент, т. е. надо применить рекурсию.
Слайд 21
Procedure QuicSort;
Procedure Sort (L, R: index);
var
i, j: index; x, w: item;
begin
i: =L; j: =R; x: =a[(L+R)div 2];
repeat
while a[i] < x do i: =i+1;
while a[j] > x do j: =j-1;
if i<= j then begin
w: =a[i]; a[i]: =a[j]; a[j]: =w;
i: =i+1; j: =j-1;
end;
until i>j;
if L if i< R then Sort (i, R);
end; {sort}
begin
Sort (1, n);
end;