Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Обработка массивов.doc
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
502.27 Кб
Скачать

Быстрая сортировка

Идея метода:

Выбираем в исходном массиве некоторый барьерный элемент x=a[k]. (В качестве барьерного элемента принято в большинстве случаев брать средний элемент a[(n+1) div 2)], n-размер массива). На втором шаге переставляем элементы массива таким образом, чтобы слева от х оказались элементы массива меньшие или равные х, а справа – элементы массива, большие х. Далее применяем предыдущие действия для каждой из полученных частей массива и т.д., пока не останутся подмассивы, состоящие из одного элемента, т.е. пока не будет отсортирован весь массив.

Программа, реализующая метод быстрой сортировки, включает в свое тело вызов следующей процедуры:

………….……………………………….

procedure sor (m,l:integer);

var i, j, x, t: integer;

begin

i:=m; j:=l;

{выбор барьерного элемента}

x:=a[(m+l) div 2];

{поиск и замена местами элементов не соответствующих данному условию}

repeat

while a[i]<x do i:=i+1;

while a[j]>x do j:=j-1;

if i<=j then

begin t:=a[i];

a[i]:=a[j];

a[j]:=t;

i:=i+1; j:=j-1;

end;

until i>j;

{рекурсивный вызов самой процедуры}

if m<j then sor(m,j);

if i<l then sor(i,l);

end;

…………………………………………………….

В этой процедуре формальные параметры m и l указывают номера первого и последнего элемента сортировки массива. При первом вызове может быть m=1, а l=n (здесь n – размер массива). Цикл repeat … until для переменных i и j используется для перемены мест элементов, не соответствующих искомому порядку. Цикл while для переменной i используется для нахождения элемента, большего «барьерного» в левой половине массива. Цикл while для переменной j используется для нахождения элемента меньшего «барьерного» и находящегося в правой половине массива. Условия m<j и i<l предназначены для очередного вызова процедуры, до тех пор, пока не останется массив, состоящий из одного элемента.

Рассмотрим принцип работы «быстрой сортировки» на примере массива

8

6

2

4

7

1

5

При вызове процедуры из основной программы с значениями m=1 и l=7 переменная i принимает значение 1, а j=7. Барьерным элементом выбирается четвертый элемент (x=a[(1+7) div 2]=a[4]=4). Цикл while для переменной i заканчивается при i=1, а цикл while для переменной j при значении j=6. После того, как поменяем местами первый и шестой элемент, получаем массив

1

6

2

4

7

8

5

и значения i=2 и j=5. Так как условие выхода из цикла не выполняется, тело цикла repeat … until выполняется еще раз. Цикл while для переменной i заканчивается при i=2, а цикл while для переменной j при значении j=4. После того, как поменяем местами второй и четвертый элемент, получаем массив

1

4

2

6

7

8

5

и значения i=3 и j=3. Так как условие выхода из цикла не выполняется, тело цикла repeat … until выполняется еще раз. Цикл while для переменной i заканчивается при i=4, а цикл while для переменной j при значении j=3. Так как i<j, элементы a[3] и a[4] остаются на месте и выполняется условие выхода из цикла repeat … until. После проверки условий m<j и i<l процедура sor вызывается с параметрами m=1, j=3 и i=4, l=7.

Для значений m=1, j=3 выполнение процедуры sor будет следующим. Барьерным элементом выбирается второй элемент (x=a[(1+3) div 2]=a[2]=4). Цикл while для переменной заканчивается при значении i=2, а цикл while для переменной j при значении j=3. После того, как поменяем местами второй и третий элемент, получаем массив

1

2

4

6

7

8

5

и значения i=3 и j=2. Условие выхода из цикла repeat … until выполняется. Условие i<l не выполняется, а выполнение условия m<j вызывает процедуру sor для значений m=1, j=2. Барьерным элементом выбирается первый элемент (x=a[(1+2) div 2]=a[1]=1). Цикл while для переменной i заканчивается при i=1, а цикл while для переменной j при значении j=1. Меняя местами первый элемент с первым элементом, мы получим

1

2

4

6

7

8

5

и значения i=2 и j=0. Условия m<j (1<0) и i<l (2<2) не выполняются. Рекурсивного вызова процедуры не происходит.

При значениях i=4 и l=7 процедура sor выполняется по следующему принципу. Барьерным элементом выбирается пятый элемент (x=a[(4+7) div 2]=a[5]=7). Цикл while для переменной i заканчивается при i=5, а цикл while для переменной j при значении j=7. После того, как поменяем местами пятый и седьмой элемент, получаем массив

1

2

4

6

5

8

7

и значения i=6 и j=6. Условие выхода из цикла repeat … until не выполняется, а циклы while заканчиваются при значениях i=6 и j=7. Так как не выполняется условие i<=j и выполняется условие i>j, из цикла repeat … until мы выходим без изменений массива.

Условия m<j (4<5), i<l (6<7) вызывают процедуру sor еще раз для значений m=4 и j=5, i=6 и l=7.

При значениях m=4 и j=5 выполнение процедуры sor протекает в следующем порядке.

Барьерным элементом выбирается четвертый элемент (x=a[(4+5) div 2]=a[4]=6). Цикл while для переменной i заканчивается при i=4, а цикл while для переменной j при значении j=5. После того, как поменяем местами четвертый и пятый элемент, получаем массив

1

2

4

5

6

8

7

и значения i=5 и j=4. Условие выхода из цикла repeat … until выполняется, и проверяются условия m<j (4<4), i<l (5<5). Не-выполнение этих условий останавливает рекурсивный вызов процедуры sor.

При значениях i=6 и l=7 выполнение процедура sor протекает в следующем порядке.

Барьерным элементом выбирается шестой элемент (x=a[(6+7) div 2]=a[6]=8). Цикл while для переменной i заканчивается при i=6, а цикл while для переменной j при значении j=7. После того, как поменяем местами шестой и седьмой элемент, получаем массив

1

2

4

5

6

7

8

и значения i=7 и j=6. Условие выхода из цикла repeat … until выполняется, и проверяются выполнение условий m<j (6<6), i<l (7<7). Так как они не выполняются, рекурсивный вызов процедуры sor прекращается.

Конечным результатом быстрой сортировки мы получим отсортированный массив

1

2

4

5

6

7

8