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

6.2.2. Алгоритм сортировки обменами (алгоритм “пузырька”)

Теория метода:

Метод “пузырька” является, пожалуй, самым простым из всех известных методов внутренней сортировки. Суть этого алгоритма состоит в последовательном просмотре массива от началу к концу и сравнении каждой пары элементов между собой. При этом если взаиморасположение не соответствует условию упорядоченности, то это устраняется путем перестановки элементов (обмена значениями). После такого прохода на последней n – ой позиции массива будет стоять максимальный элемент («всплыл» первый пузырек). Поскольку максимальный элемент уже стоит на своей последней позиции, то второй проход обменов выполняется до n-1 –го элемента. И так далее. Всего потребуется n-1 проход.

Рассмотрим этот процесс на примере. Пусть исходный массив M состоит из 5 элементов и имеет вид:

5 9 3 6 1

Процесс сортировки представлен на схеме:

1- й проход

2- й проход

3- й проход

4- й проход

5 9 3 6 1|

3 9

6 9

1 9

5 3 6 1 |9

3 5

1 6

3 5 1 |6 9

1 5

3 1 |5 6 9

1 3

После сортировки массив выглядит так:

1 3 5 6 9

Во время первого прохода произойдут три перестановки: 9—3, 9—6 и 9—1. На втором проходе будут переставлены 5 и 3, а затем 6 и 1. Третий и четвертый проход даст только по одной перестановке соответственно — 5 и 1, 3 и 1.

Одна из возможных версий программы, реализующей алгоритм “пузырька”, представлена на языке программирования Паскаль в следующем виде:

Program Sort_Bull; {сортировка методом "пузырька"}

uses Сrt;

const n=10; {длина массива}

type

Mas = array[1..n] of real;

var

M : mas; В :real ;

i, j : integer; {счетчики}

begin

СlrScr;

Writeln('Bвeдитe элементы массива');

for i :=1 to n do Read(M[ i ]) ;

Readln;

{начало сортировки}

for i:=n downto 2 do

{всплывание очередного максимального элемента на i позицию }

for j : =1 to i-1 do

if M[j]>M[j+1] then {обмен содержимым ячеек}

begin В : = M[j +1 ] ;

M[j+1]:=M[j ];

M[j]:=B

end;

{печать отсортированного массива}

for i : = 1 to n do

Wгite (M[i] : 8 : 2 );

Writeln

End.

“Пузырьковая” сортировка имеет очень плохие временные характеристики - ее трудоемкость выражается величиной вида O(n2), где n - размер массива. В связи с этим она имеет только учебно-исторический интерес и не может быть рекомендована для практического использования.

6.2.3. Усовершенствованная "пузырьковая" сортировка

Испытаем пузырьковый алгоритм еще на одном наборе чисел: 4 7 11 15 20 13 (п = 6). Как видим, в данном случае массив с самого начала почти упорядочен, но, используя ранее рассмотренный метод сортировки (метод пузырька), мы можем отсортировать его за n-1 проход.

1-ый 2-ой 3-ий 4-ый 5-ый

проход проход проход проход проход

4

7

11

15

20 13

13 20

4

7

11

15 13

13 15

20

4

7

11

13

15

20

4

7

11

13

15

20

4

7

11

13

15

20

На схеме приведенной ниже видно, что после двух проходов элементы выстроились в правильном порядке, и на очередных проходах (от 3 до n-1) не было сделано ни единого обмена. Совершенно ясно, что надо окончить процесс сортировки, не делая бессмысленные сравнения. Обычно в подобных случаях прибегают к услугам некоторой «флажковой» переменной, ложное значение которой сигнализировало бы об отсутствии перестановок, тогда как значение «истина» указывало бы, что перестановки имели место. На эту роль идеально подходит переменная типа boolean, поскольку ее значениями могут быть лишь две величины — false и true. Таким образом, усовершенствованный вариант программы сортировки обменом может быть представлен в таком виде:

Program Sort_Bull_1; {сортировка методом "пузырька"}

uses Сrt;

const n=10; {длина массива}

type

Mas = array [1..n] of real;

var

M : mas; В :real ;

i: integer; {счетчик}

Flag: boolean;

begin

СlrScr;

Writeln('Bвeдитe элементы массива');

for i :=1 to n do Read (M[ i ]) ;

Readln;

repeat {начало сортировки}

Flag := false;

for i := 1 to n-1 do

if M[i] > M[i+1] then

begin

Flag : = true ;

B := M[i] ;

M[i] := M[i+1] ;

M[i+1] := B

end { if . . .then }

until not Flag

{печать отсортированного массива}

for i : = 1 to n do

Wгite (M[i] : 8 : 2 );

Writeln

End.

Как видим, блок сортировки содержит два цикла, и каждый из них выполняет в ней свою собственную задачу. Внешний цикл repeat-until занимается лишь тем, что постоянно «прокручивает» внутренний цикл for, пока не обнаружит, что при очередном просмотре ряда не произошло ни одной перестановки элементов. Задачей же цикла for является последовательное сравнение всех пар смежных элементов в массиве М. За один шаг внешнего цикла внутренний всегда совершает ровно п — 1 шагов. Количество повторений внешнего цикла заранее неизвестно, а определяется возникновением события Flag = false.

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