- •2003-2004 Программирование. 1 курс. Лектор: доцент Певзнер л.В.
- •5.9. Сортировка и поиск
- •5.9.1. Сортировка
- •А. Сортировка выбором
- •B. Сортировка включением
- •C. Сортировка обменом
- •D. Сортировка слиянием
- •E. Внешняя сортировка
- •5.9.2. Поиск
- •5.9.3. Примеры сортировок
- •A. Пример сортировки выбором
- •B. Пример сортировки включением
- •C. Пример сортировки обменом
- •D. Пример сортировки слиянием
C. Сортировка обменом
Эту сортировку иногда называют сортировкой «Пузырьком».
Дано: Последовательность элементов М={M[1], M[2], …, M[n]}.
Необходимо: Упорядочить эту последовательность по убыванию (по возрастанию действия будут выполняться по аналогичной схеме).
Схема сортировки будет следующая:
1. Сравнить два первых элемента А и В, если А<В, то поменять их местами.
2. Сравнить второй и третий элементы В и С. Если В меньше С, то поменять их местами.
3. Продолжить процесс сравнения до конца множества (массива). При этом минимальный элемент окажется на последнем месте.
4. Выполнить шаги 1-3, начиная от первого элемента до найденного на предыдущем шаге минимального. Процесс закончен, как только мы выполнили шаг 4 -- (n-1) раз.
Упражнение 4.
Оцените этот алгоритм самостоятельно.
D. Сортировка слиянием
Дана последовательность элементов М. Для простоты снова предположим, что мощность этого множества = n.
Тогда схема этого алгоритма сортировки будет следующая:
1. Разбить множество М на два равных М1 и М2.
2. Упорядочить каждое из этих множеств (но по одному признаку, то есть или по возрастанию, или по убыванию).
3. «Слить» эти множества в одно.
Заметим, что общее время работы такого алгоритма = O(n*log2n).
E. Внешняя сортировка
Сортировка информации, хранящейся в файлах на дисках, называется внешней. Многие способы внутренней сортировки, описанные выше, без изменения применимы и к данным, расположенным во внешней памяти.
Например, построение двоичного дерева по набору признаков, хранящихся в файле. (Здесь можно использовать любой из изученных файлов – текстовый, типизированный, нетипизированный).
Упражнение.
Записать все рассмотренные выше алгоритмы сортировок, учитывая тот факт, что исходная информация хранится в одном файле. Тип и структуру файла установить самостоятельно.
Интересным является алгоритм внешней сортировки, при котором, информация хранится в двух или более файлах. В этом случае лучше использовать один из алгоритмов сортировки слиянием. В этом случае, каждый из файлов должен быть упорядочен. Причем упорядочение всех файлов, участвующих в сортировке должно быть по одному признаку (по возрастанию, или убыванию).
5.9.2. Поиск
Поиском называется процесс нахождения элемента в множестве данных.
Поиск является наиболее эффективным, если исходное множество данных отсортировано, то есть упорядочено по данному ключу.
Рассмотрим сложность алгоритма поиска в неупорядоченном множестве.
Пусть дано множество М={а1, а2, …, аn}. Данное множество произвольное, то есть неупорядоченное. Тогда алгоритм поиска элемента А в множестве М будет стандартным, то есть, необходимо сравнивать каждый элемент М[i] с требуемым элементом А (или проверять его, удовлетворяет ли данный элемент требуемому критерию – например, является ли он наименьшим) до тех пор, пока не будет найден исходный элемент А или пока множество М не будет полностью рассмотрено, а элемент А, удовлетворяющий требуемому критерию так и не найден. Тогда сложность по времени алгоритма поиска элемента А в данном множестве будет О(n), где n – мощность множества М.
Для ускорения алгоритма поиска обычно используют различные стратегии. Одна из них получила название «Разделяй и властвуй». В этой стратегии, исходное множество разбивается на два (М1 и М») по [n/2] в одном множестве и (n-[n/2]) элементов в множестве. Если использовать рекурсивную процедуру, то можно более эффективный по времени алгоритм. Рассмотрим данную стратегию на примере следующей задачи.
Пример
Дано множество М={а1, а2, …, аn}. Для простоты предположим, что мощность М есть степень числа 2. Необходимо найти в нем наименьший и наибольший элемент. Очевидный путь нахождения этих элементов, это поиск каждого их них по отдельности.
Например, процедура нахождения максимального элемента
Max:=M[1];
Для i:=1 до n Выполнить
Если M[i]>Max то Max:=M[i]
Будет выполняться за (n-1) сравнений.
Для нахождения наименьшего элемента из остальных (n-1) элементов необходимо выполнить как минимум (n-2) сравнения.
Таким образом, для нахождения максимального и минимального элемента при n>=2 требуется (2n-2) сравнений.
Если же использовать стратегию «Разделяй и властвуй», то алгоритм решения этой задачи можно записать следующим образом:
К последовательности М применяется рекурсивная процедура MAXMIN. Она имеет два входных аргумента – вышеописанное множество М и его мощность. Эта процедура формирует пару (Max, Min).
Заметим, что сравнение элементов множества М происходит только на шаге 3 (сравниваются 2 элемента – множество состоит только их двух элементов) и на шаге 7 ( где сравниваются max1 и max2, min1 и min2). Индукцией можно доказать, что общее число сравнений будет Т(n)=(3/2)*n-2. Сравните с (2n-2)!
Эффективность хорошо видна при достаточно большом n.
Например, пусть n=100 000 000. Тогда, по первому алгоритму мы имеем количество сравнений = 199 999 998 , по второму = 149 999 998. Разница= 50 000 000 При n=100 000 000 000. Тогда, по первому алгоритму мы имеем количество сравнений = 199 999 999 998, по второму = 149 999 999 998. Разница=50 000 000 000.
Заметим, что в данном случае мы имели дело с неупорядоченным множеством.
Упражнение.
1. Написать процедуру MinMax на Object Pascal.
2. Написать главный модуль, осуществляющий ввод информации в массив (множество), вызов этой процедуры и печать результата (то есть, напечатать, принадлежит ли элемент множеству, и если “да”, то порядковый номер этого элемента в множестве.
Эту же стратегию можно применить и при поиске элемента А в упорядоченном множестве М.
Пример
Необходимо определить, принадлежит ли А множеству М, где индексы множества принадлежат диапазону [d1,d2], и найти порядковый номер этого элемента А.
Такой алгоритм обычно называют алгоритмом “двоичного поиска”, или метод деления множества пополам.
Упражнение.
1. Найти оценку приведенного в пример 2 алгоритма. Сравнить эту оценку с стандартным алгоритмом поиска (полным перебором). (логарифмы!)
2. Написать главный модуль, осуществляющий ввод информации в массив (множество), вызов этой процедуры и печать результата (то есть, напечатать, принадлежит ли элемент множеству, и если “да”, то порядковый номер этого элемента в множестве.
В примере необходимым требованием является упорядочение множества элементов.
Заметим, что задача MinMax решается очень просто, если множество (массив) упорядочено (просто берутся первый и последний элементы массива).
Упражнение. (Выполнить хотя бы приближенно, по аналогии с описанным выше)
1. Найти оценки процесса поиска элемента в двоичном несбалансированном дереве.
2. Найти оценки процесса поиска элемента в двоичном сбалансированном дереве. Сравнить с оценкой поиска в несбалансированном дереве.