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

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

Эффективность двоичного поиска и общая обстановка в стране убедительно свидетельствуют в пользу порядка. В этом разделе мы рассмотрим несколько алгоритмов упорядочения массивов.

4.1 Обменная сортировка

Задан массив из n чисел, например:

50 40 10 60 30 20.

Пройдем вдоль массива, сравнивая на каждом шаге пару соседних чисел: 1-е со 2-м, 2-е с 3-м и т.д. Если левое число окажется больше правого, будем менять их местами. Получим:

40 10 50 30 20 60.

Полного порядка пока не получилось, но самое большое число в массиве попало на свое законное место. Проделаем то же самое еще раз:

10 40 30 20 50 60.

Теперь уже два числа в массиве, 50 и 60, занимают свои места. Нетрудно понять, что после (n-1)-го прохождения, а возможно и раньше, все числа в массиве станут на свои места, и он будет полностью упорядочен:

10 30 20 40 50 60.

10 20 30 40 50 60.

Запишем этот алгоритм.

Начало

Установить в 1 счетчик прохождений, Run = 1;

Пока Run < n -1 повторять

Начало

Пройти массив, сравнивая пары чисел;

Увеличить на 1 счетчик прохождений, Run = Run + 1;

Конец

Конец

Детализируем оператор "Пройти массив, сравнивая пары чисел", полагая, что числа хранятся в массиве M.

Начало

Установить в 1 счетчик элементов массива, count = 1;

Пока count <= (n - Run) повторять

Начало

Если M[count]>M[count+1], то M[count] <=> M[count+1];

count = count + 1;

Конец

Конец

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

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

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

Процедура Прохождение (M, Run)

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

Окончательно алгоритм обменной сортировки примет вид:

Начало

Установить в 1 счетчик прохождений, Run = 1;

Пока Run < n-1 повторять

Начало

Прохождение (M, Run);

Увеличить на 1 счетчик прохождений, Run = Run + 1;

Конец

Конец

Процедура Прохождение (M, Run);

Начало

Установить в 1 счетчик элементов массива, count = 1;

Пока count <= (n - Run) повторять

Начало

Если M[count]>M[count+1], то M[count] <=> M[count+1];

count = count + 1;

Конец

Конец

4.2 Сортировка слиянием

Чтобы лучше понять смысл сортировки слиянием, отдельно рассмотрим алгоритм слияния.

З а д а ч а. Даны два упорядоченных массива A и B. Слить их в третий массив C, тоже упорядоченный.

Р е ш е н и е.

Сравним первые элементы сливаемых массивов, A[1] и B[1]. Меньший из них поместим в начало массива С и вычеркнем из исходного массива. Снова сравним два первых, не вычеркнутых элемента массивов A и B, меньший перепишем в C и вычеркнем и т.д., пока один из исходных массивов не исчерпается. Тогда перепишем в C остаток другого массива и слияние закончено.

Более точно все это можно записать в виде следующего алгоритма.

Начало

Обнулить счетчик вычеркнутых элементов массива А, СrossA = 0;

Сделать то же для массива В, СrossB = 0;

Обнулить счетчик элементов, записанных в массива C, WriteC = 0;

Пока в обоих массивах есть не вычеркнутые элементы повторять

Начало

ЕслиA[CrossA+1] < B[CrossB+1]то Начало

переписать в С из А, C[WriteC+1] = A[CrossA+1];

вычеркнуть элемент из А, CrossA = CrossA+1;

Конец иначе Начало

переписать в С из В, C[WriteC+1] = B[CrossB+1];

вычеркнуть элемент из В, CrossB = CrossB+1;

Конец

Увеличить счетчик записи в C, writeC = writeC+1;

Конец

Еслимассив А исчерпан, CrossA = nA,то

переписать в массив С остаток массива В;

Еслимассив В исчерпан, CrossВ = nВ,то

переписать в массив С остаток массива А;

Конец

Массив C будет полностью упорядочен, т.к. числа, которые попали туда раньше, меньше тех, что попали туда позже.

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

,

где n — общее количество элементов в массивах А и В.

Вернемся к сортировке слиянием. Даже в неупорядоченном массиве можно обнаружить упорядоченные участки. Тривиальным будет утверждение, что любой массив состоит из упорядоченных участков единичной длины.

Разобьем сортируемый массив на две половины, А1 и В1, каждую из которых станем рассматривать как массив, состоящий из упорядоченных участков единичной длины.

Соединим их, применяя алгоритм слияния к упорядоченным участкам. Результаты слияния очередной пары участков будем заносить попеременно в два новых массива, А2 и В2. В новых массивах упорядоченные участки будут иметь длину, равную сумме длин исходных участков, т.е. 2.

Сольем теперь упорядоченные участки массивов А2 и В2, попеременно записывая результаты в освободившиеся массивы А1 и В1. Длина упорядоченных участков снова удвоится и станет равна 4.

Будем повторять слияние массивов, каждый раз меняя ролями пары (А1, В1) и (А2, В2), пока длина упорядоченного участка не сравняется с длиной исходного массива. В этот момент сортировку можно считать законченной.

Запишем сказанное в виде алгоритма.

Начало

Разбить сортируемый массив на две половины, А1 и В1;

Установить начальную длину упорядоченного участка, d = 1;

Пока d < n повторять Начало

Слить входные массивы, и получить два выходных массива;

Удвоить длину упорядоченных участков, d = d * 2;

Сделать выходные массивы входными и наоборот;

Конец

Конец

Алгоритм сортировки слиянием не разработан здесь до той степени, что обменная сортировка. Его полную детализацию и программирование вы должны выполнить самостоятельно.

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