Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по программированию.doc
Скачиваний:
7
Добавлен:
17.04.2019
Размер:
1.6 Mб
Скачать

3.3. Сортировка одномерного массива

Сортировка — перестановка местами объектов в определенном порядке. Известно несколько сотен алгоритмов сортировки и их модификаций.

Пусть дана последовательность элементов – A1, А2, …, Аn. Сортировка означает перестановку этих элементов в новом порядке Аk1 , Аk2, …, Akn. Этот порядок соответствует значениям некоторой функции F, такой, что справедливо отношение F(Ak1) < F(Ak2)< ... <F(Akn).

Как у любого вычислительного процесса у сортировки есть свои критерии для сравнительной оценки качества программы и соответствующего ей алгоритма. Такими критериями являются: объем используемой памяти и время работы программы.

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

При оценке времени сортировки используют два показателя: число сравнений ключей (С), число пересылок данных (М). Хорошими по времени считаются сортировки, в которых число сравнений С=N*Ln(N). К простым, то есть не очень хорошим, относятся такие сортировки, в которых число сравнений пропорционально квадрату размерности N исходного массива С≈N2. Следует отметить, что показатели С и М существенно зависят от первоначальной упорядоченности сортируемого массива. Наиболее тяжелым (Мах) считается случай, когда массив упорядочен в обратном порядке. Ниже мы рассмотрим три наиболее известных способа сортировки одномерного массива. Сравнительные временные характеристики этих способов приведены в следующей таблице:

Способ

Min

Средний

Max

Метод Пузырька

C = (N2 -N)/2,

М = 0

C = (N2 -N)/2,

M = 0.75·(N2-N)

C = (N2 -N)/2,

M = 1.5· (N2-N)

Простой выбор

C = (N2-N)/2,

M = 3· (N-1)

C = (N2 -N)/2,

M = N· (Ln(N) + 0.57)

C = (N2-N)/2,

M = N2/4 + 3· (N-l)

Простое включение

C = N-1,

M = 2· (N-1)

C = (N2+N-2)/4,

M = (N2-9N-10)/4

C = (N2 -N)/2-l,

M = (N2 +3N-4)/2

Сортировка простым обменом. Метод пузырька

Пример 32.

Методом пузырька упорядочить (отсортировать) в порядке возрастания массив из 8 целых чисел (44, 55, 12, 42, 94, 18, 06, 67).

Концептуальную модель сортировки рассмотрим на примере восьми целых чисел, которые расположим в первом вертикальном столбце. Вертикальное расположение сортируемого массива наглядно иллюстрирует «всплывание легких элементов (чисел) вверх к поверхности» по мере сортировки массива.

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

Индекс элемента массива

Номер прохода сортировки (I)

1

2

3

4

5

6

7

8

J=1

4 4

06

06

06

06

06

06

06

2

55

44

12

12

12

12

12

12

3

12

55

44

18

18

18

18

18

4

42

12

55

44

42

42

42

42

5

94

42

18

55

44

44

44

44

6

18

94

42

42

55

55

55

55

7

06

18

94

67

67

67

67

67

8

67

67

67

94

94

94

94

94

Элементы всплывают вверх к поверхности в соответствии с их весами, пока не встретят элемент с более малым весом. С каждым проходом наиболее легкий элемент из оставшихся поднимается на свое место, показанное жирными цифрами. Таким образом, нет необходимости на каждом проходе проверять элементы, стоящие выше выделенных, поскольку они уже отсортированы ранее. Начиная с 6 прохода, состояние массива не изменяется, что объясняется начальной упорядоченностью элементов в исходном массиве.

Эта программа предназначена для изучения сортировки методом пузырька, поэтому взят массив из восьми целых чисел. Массив заранее известен, следовательно, инициализировать Х[1...8] проще всего в разделе констант. Ввод данных с клавиатуры в этой программе не требуется. Алгоритм программы представляет собой двойной вложенный цикл. Индекс I внешнего арифметического цикла соответствует номеру прохода сортировки. Индекс J это номер элемента в массиве. Для перестановки двух соседних элементов X[J-1] и X[J] местами используется промежуточная рабочая ячейка с идентификатором L.

P ROGRAM PR32;

CONST

X: ARRAY [1.. 8] OF INTEGER = (44, 55,12,42,94,18,06, 67);

VAR

L, I, J: INTEGER;

BEGIN

{ Вывод на экран исходного массива X }

FOR I := 1 ТО 8 DO WRITE(X[I]:5);

WRITELN;

FOR I := 2 TO 8

DO FOR J:=8 DOWNTO I

DO IF X[J-1] > X[J]

THEN BEGIN{Переставить X[J-1] с Х[J] местами}

L:=X[J-1];

X[J-1]:=X[j];

X[J]:=L

END; {IF}

{ Вывод на экран отсортированного массива X }

FOR I := 1 ТО 8 DO WRITE(X[I]:5);

WRITELN

END.

Сортировка простым включением

Пример 33

Методом простого включения упорядочить (отсортировать) в порядке возрастания массив из 8 целых чисел (44, 55,12,42, 94, 18, 06, 67).

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

PROGRAM PR33;

CONST

X: ARRAY [1.. 8] OF INTEGER = (44, 55,12,42, 94,18,06, 67);

VAR

L, I, J: INTEGER;

BEGIN { Вывод на экран исходного массива X }

FOR I := 1 ТО 8 DO WRITE(X[I]:5);

WRITELN;

FOR I:=2 TO 8

DO BEGIN

J:= I-1; L:= X[I];

WHILE (J > 0) AND (L < Х[I])

DO BEGIN { Переставить Х[J] на место Х[J+1]}

X[J+1]:=X[J];

J:=J-1;

END; X[J+1]:=L END;

{ Вывод на экран отсортированного массива X}

FOR I := 1 ТО 8 DO WRITE(X[I]:5);

WRITELN

END.

Сортировка простым выбором

Пример 34.

Методом простого выбора упорядочить (отсортировать) в порядке возрастания массив из 8 целых чисел (44, 55,12,42, 94,18, 06, 67).

Этот метод более предпочтителен, чем сортировка простым включением. Концептуальная модель этого метода состоит в следующем. Начиная с первой позиции, просматриваются все N элементов и находится номер К наименьшего из элементов. Элемент К ставится на первое место. А элемент, стоявший на втором месте, перемещается на место К. На втором проходе I = 2 первый элемент уже не рассматривается. Рассматриваются оставшиеся N-1 элементы и среди них находится наименьший элемент, имеющий номер К. Этот элемент ставится на второе место, а элемент со второго места смещается на место К.

Этот процесс продолжается до тех пор, пока не будет просмотрен весь массив X, содержащий N элементов.

PROGRAM PR34;

CONST

X: ARRAY [1.. 8] OF INTEGER = (44, 55,12,42,94, 18,06,67);

VAR

K,L, I, J: INTEGER;

BEGIN { Вывод на экран исходного массива X }

FOR I := 1 ТО 8 DO WRITE(X[I]:5);

WRITELN;

FOR I := 1 TO 7

DO BEGIN

K:= I;

FOR J := I + 1 TO 8 { Поиск номера К наименьшего X[I]... Х[К]}

DO IF Х[J] < X[K] THEN К := J;

{ Переставить Х[K] на место Х[I]}

L:=X[I];

X[I] := Х[К];

Х[К] := L;

END;

{ Вывод на экран отсортированного массива X }

FOR I := 1 ТО 8 DO WRITE(X[I]:5);

WRITELN

END.

Из всех примеров нетрудно заметить одно существенное неудобство, связанное с использованием регулярных типов. Оно состоит в том, что необходимо сразу фиксировать число элементов массива. В отдельных случаях заранее не известна размерность массива, подлежащего обработке. Например, может возникнуть необходимость в одном случае отсортировать массив в 20 вещественных чисел, а в другом 100. Поэтому в программу приходится вносить исправления. Здесь помогает понятие константы, описанной в разделе CONST. Достаточно заменить описание N = 20 на N = 30, или N = 100 и больше никаких исправлений в программе не потребуется. Либо использовать переменную N, значение которой вводится либо пользователем с клавиатуры, либо присваивается в программе.