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

Алгоритм быстрой сортировки

Алгоритм принадлежит Хоару (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) элемента.

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

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]