Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты на зачет.docx
Скачиваний:
57
Добавлен:
01.06.2015
Размер:
554.66 Кб
Скачать

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

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

Основная идея алгоритма состоит в том, чтобы отсортировать все группы файла состоящие из элементов файла отстоящих друг от друга на расстояние h. Такие файлы называются h-сортированными. Когда мы h-сортируем файл по некоторому большому h, мы передвигаем его элементы на большие растояния. Это облегчает работу сортировки для меньших значений h. Процесс заканчивается когда h уменьшается до 1.

рисунок 7 Оболочечная Сортировка

vara : array [1..N] of integer;procedureShellSort1;vari, j, h, v : integer;beginh := 1;repeath := h * 3 + 1untilh>100;repeath:=hdiv3;fori := h+1toNdobeginv := a[i]; j:=i;while(a[j-h]>v)and(j>h)dobegina[j] := a[j–h]; j := j – h;end; a[j] := v;end;untilh = 1;end;

На рисунке 7 показано, как сортировка Шелла обрабатывает файл с шагом в ..., 13, 4, 1. Серым фоном обозначается сортируемый на данном шаге подфайл.

Приведенная программа использует последовательность ... 1093, 364, 121, 40, 13, 4, 1. Могут существовать и другие последовательности – одни лучше, другие хуже.

Свойство 6 Оболочечная сортировка никогда не делает более чем N1.5 сравнений для вышеуказанной последовательности h.

Подсчет Распределения

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

forj:=0toM-1docount[j]:=0;fori:=1toNdoinc(count[a[i]] );forj:=0toM-1docount[j]:=count[j-1]+count[j];fori:=Ndownto1dobeginb[count[a[i]]] := a[i]; dec(count[a[i]]);end; a := b;

35. Алгоритмы быстрой сортировки, разрядная сортировка Алгоритм быстрой сортировки

Алгоритм принадлежит Хоару (CharlesAntonyRichardHoare), который опубликовал и тщательно проанализировал его в 1962 году.

Суть алгоритма основана на обмене элементов с разделением, поэтому иногда его называют обменной сортировкой с разделением.

Выберем случайным образом какой-то элемент массива, обозначим его yи будем называть его опорным элементом. Проблема выбора опорного элемента будет рассмотрена отдельно.

Наша задача разделитьмассив на две части – левую, с элементами меньшимиyи правую с элементами большимиy. Будем просматривать массив с двух сторон. Двигаясь слева направо, найдем элементx[i]>y, а, двигаясь справа налево, найдем элементx[j]<y.Поменяем их местами и продолжим просмотр до тех пор, пока не встретимся в каком-то месте массива. Понятно, что после такого прохода массив будет разделен по принципу: слева стоят все элементы меньшие опорного, а справа – все элементы большие или равные.

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

Пример разделения 1 (по Кормену): в качестве опорного элемента выбран y=x[1]=5:

5

3

2

6

4

1

3

7

3

3

2

6

4

1

5

7

3

3

2

1

4

6

5

7

Пример разделения 2 (по Вирту): в качестве опорного элемента выбран средний элемент y=42:

44

55

12

42

94

06

18

67

18

55

12

42

94

06

44

67

18

06

12

42

94

55

44

67

Пример разделения 3 (по Кнуту-Седгевику): в качестве опорного элемента выбран первый элемент y=50, просмотр начинается со 2 элемента, затем происходит обменjэлемента с 1

:

50

8

51

98

42

15

67

73

50

8

15

98

42

51

67

73

50

8

15

42

98

51

67

73

48

8

15

50

98

51

67

73

{Partition по Вирту} i := 1; j := n; {выбор опорного элемента y}; repeatwhilex[i] < ydoi := i + 1;whilex[j] > ydoj :=j – 1;ifi<= jthenbegin z := x[i]; x[i] := x[j]; x[j] := z; i :=i + 1; j := j – 1end;untili > j;

Заметим, что при сравнении whilex[i]<y(whilex[j]>y), ищется элемент неx[i]>yаx[i]>=y(соответственно справа не <, а <=), то естьyдействует как барьерный элемент.

В рассмотренном примере 1 разделения массива, после завершения разделения значения индексов равны: i = 6,j = 5. Заметим, что условиеifi<=jthenпредшествующее обмену необходимо – без него мы ошибочно бы обменяли местами 4 и 6.

В рассмотренном примере 2 разделения массива, после завершения разделения значения индексов равны: i = 5,j = 3.

Все элементы разделились по принципу:

x[k]<=y, k=1,…i-1;

x[k]>=y, k=j+1,n,

x[k]=y,k=j+1,…i-1.

Рассмотрим теперь разделение массива:

2

3

7

1

6

5

4

1

3

7

2

6

5

4

После завершения разделения значения индексов равны: i = 2,j = 1. Здесь выбор среднего элемента в качестве опорного является неудачным, так как после деления имеем разбиение на левую часть из 1 элемента и правую часть из (n-1) элемента.

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