Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы_по_проге_Берлин / Книги / учебное пособие ОАиП.pdf
Скачиваний:
49
Добавлен:
11.02.2015
Размер:
947 Кб
Скачать

каждого этапа отстоящие на gap элементы отсортированы.

Рассмотрим пример. Рассортировать массив чисел: 41,53,11,37,79,19,7,61. В строке после массива в круглых скобках указаны индексы

сравниваемых элементов и указан номер внешнего цикла.

41

53 11 37 79 19

7

61

– исходный массив.

 

 

 

 

41

19 11 37 79 53

7

61

– (0,4), (1,5)

 

 

 

1-ый цикл

 

 

 

41

19

7 37 79 53

11

61

– (2,6), (3,7)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

7

19 41 37 11 53

79

61

– (0,2),(1,3),(2,4),(3,5),(4,6),(5,7)

 

 

2-ой цикл

 

7

19 11 37 41 53

79

61

– (0,2),(1,3),(2,4),(3,5),(4,6),(5,7)

 

 

 

 

 

 

 

7

11 19 37 41 53

61

79

– сравнивались соседние.(3-ий цикл).

void sort(int *ms, int k)

 

 

 

 

 

 

 

 

 

{ int i, j, n;

 

 

 

 

 

 

 

 

 

 

 

int

gap;

// шаг сортировки

 

 

 

 

 

int

flg;

// флаг окончания этапа сортировки

for(gap = k/2; gap > 0; gap /= 2) do

{flg = 0;

for(i = 0, j = gap; j < k; i++, j++)

if(*(ms+i) > *(ms+j)) // сравниваем отстоящие на gap элементы

{n = *(ms+j); *(ms+j) = *(ms+i); *(ms+i) = n;

flg = 1;

// есть еще не рассортированные данные

}

 

} while (flg);

// окончание этапа сортировки

}

Метод Хора

Алгоритм быстрой сортировки построен на основе идеи разбиения массива на разделы. Общая процедура заключается в выборе пограничного значения, называемого компарандом, которое разбивает сортируемый массив на две части. Все элементы, значения которых больше пограничного значения, переносятся в один раздел, а все элементы с меньшими значениями - в другой. Затем это процесс повторяется для каждой из частей и так до тех пор, пока массив не будет отсортирован. Например, допустим, что необходимо отсортировать следующий массив: "fedacb". Если в качестве компарадера использовать "d", то после первого прохода алгоритм быстрой сортировки упорядочит массив следующим образом

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

Fedacb

Проход 1

Bcadef

Затем этот подход повторяется для каждого раздела, а именно "bca" И

"def".

Проход 2

Acb

Def

Проход 3

Abc

Def

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

Метод Хоора (Charles Antony Richard Hoare, 1962 г.), называемый также методом быстрой сортировки (Quicksort) основывается на следующем: находится такой элемент, который разбивает множество на два подмножества так, что в одном все элементы больше, а в другом - меньше делящего. Каждое из подмножеств также разделяется на два, по такому же признаку. Конечным итогом такого разделения станет рассортированное множество. Рассмотрим один из вариантов реализации сортировки Хоора.

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

Например, необходимо рассортировать массив: 13,3,23,19,7,53,29,17. Переставляемые элементы будем подчёркивать, средний - выделим жирным шрифтом, а элемент попавший на своё место и не участвующий в последующих сравнениях - наклонным шрифтом. Индекс i будет задавать номер элемента слева от среднего, а j справа от среднего.

13

3 23

19

7 53 29 17

13

3 17

19

7 53 29 23

13

3 17

7 19 53 29 23

делим на два подмножества

13

3

17

7

19 53 29 23

Выделяем подмножество

 

 

 

 

 

 

 

 

 

3

13

17

7

19 23 29 53

 

 

 

 

 

 

 

 

 

 

 

13

17

 

7

 

 

 

 

Выделяем подмножество 13

7

 

 

17

 

 

 

 

Результат:

 

3

 

7

 

13

17

 

19 23 29 53

//

l – левая r – правая границы сортируемого массива

void hoar(int

*ms, int

l, int r) // передаем левую/правую границы

{

int

i, j, k;