- •Предисловие
- •Основы программирования
- •Понятие алгоритма.
- •Алгоритм Евклида.
- •Задача о поездах и мухе
- •Вместо лирического отступления
- •Этапы подготовки задачи для решения на компьютере
- •Примеры разработки алгоритмов
- •Решение квадратного уравнения.
- •Вычисление интегралов
- •Обработка результатов эксперимента
- •Решение системы линейных алгебраических уравнений
- •Введение в язык программирования Pascal
- •Основные элементы языка
- •Переменные. Стандартные типы.
- •Операции отношения
- •Раздел описаний переменных
- •Выражения. Порядок выполнения операций.
- •Константы
- •Комментарии в программе
- •Операторы
- •2.1.7.1. Оператор присваивания
- •2.1.7.2. Операторы ввода/вывода
- •2.1.7.3. Операторы инкремента и декремента
- •Среда разработки Lazarus
- •Русский язык в консольных приложениях
- •Первая программа
- •Открытие существующего проекта
- •Другие способы создания консольных приложений
- •Типовой пустой проект
- •Операции с целыми числами
- •Вместо лирического отступления 2
- •Стандартные функции с целыми аргументами
- •Операции с вещественными числами (тип real).
- •Форматирование вывода
- •Одновременное использование вещественных и целых чисел.
- •Другие стандартные функции с вещественными аргументами
- •Булевы переменные
- •Условные операторы.
- •2.1.22.1 Оператор if …. then
- •2.1.22.2. Оператор if …then ... else
- •Операторы цикла
- •2.1.23.1. Оператор цикла с предусловием
- •2.1.23.2. Оператор цикла с постусловием
- •2.1.23.3. Оператор цикла с параметром.
- •2.1.23.4. Второй вариант оператора цикла с параметром
- •Оператор выбора case
- •Организация простейшего контроля ввода данных.
- •Вычисление сумм сходящихся рядов
- •Реализация некоторых алгоритмов главы 1.
- •Программа решения задачи о поездах и мухе
- •Программа вычисления определенного интеграла
- •Более сложные элементы языка
- •Общая структура Паскаль – программы
- •Процедуры и функции
- •3.1.1.1 Структура процедуры
- •3.1.1.2. Структура функции
- •3.1.1.3 Глобальные и локальные переменные
- •3.1.1.4 Способы передачи параметров
- •3.1.1.5 Процедуры завершения
- •Еще раз о типах данных
- •Классификация типов данных
- •3.2.1.1 Целый тип
- •3.2.1.2. Интервальный тип
- •3.2.1.3. Перечислимый тип
- •3.2.1.4. Множества
- •3.2.1.5. Логический тип
- •3.2.1.6. Вещественный тип
- •3.2.1.7. Указатели
- •Обработка символьной информации в Паскале
- •Символьные и строковые типы данных.
- •3.3.1.1. Тип Char
- •3.3.1.2. Функции для работы с символами
- •3.3.1.3. Тип String
- •3.3.1.4. Строковые процедуры и функции
- •Массивы
- •Динамические массивы
- •Программа решения системы линейных алгебраических уравнений методом Гаусса
- •3.4.1.1. Вариант 1 – с goto
- •3.4.1.2. Вариант 2 – без goto
- •3.4.1.3. Вариант 3 – наилучшая реализация
- •Модули в Паскале
- •Структура модуля
- •Системные модули
- •3.5.2.1. Модуль CRT
- •Файлы
- •Тип данных – запись
- •Файловые типы
- •Процедуры для работы с файлами
- •3.6.3.1. Общие процедуры для работы с файлами всех типов
- •3.6.3.2. Процедуры для работы с текстовыми файлами
- •3.6.3.3. Процедуры для работы с типизированными файлами
- •3.6.3.4. Процедуры для работы с нетипизированными файлами
- •3.6.3.5. Организация контроля ввода/вывода при работе файлами
- •3.6.3.6. Создание простой базы данных с типизированными файлами.
- •Алгоритмы сортировки
- •Обменная сортировка (метод "пузырька")
- •Сортировка выбором
- •Сортировка вставками
- •Метод быстрой сортировки
- •Алгоритмы поиска
- •Поиск в массивах
- •Вставка и удаление элементов в упорядоченном массиве
- •Динамические структуры данных
- •Представление в памяти компьютера динамических структур.
- •Реализация стека с помощью массивов
- •Указатели
- •Стандартные операции с линейными списками
- •Реализация динамических структур линейными списками
- •4.3.6.1. Реализация стека
- •4.3.6.2. Реализация очереди с помощью линейного списка
- •4.3.6.3. Реализация двоичного дерева с помощью линейного списка
- •Сортировка и поиск с помощью двоичного дерева
- •Три источника и три составные части ООП.
- •Классы и объекты.
- •Обращение к членам класса.
- •Инкапсуляция
- •Спецификаторы доступа.
- •Свойства.
- •Наследование
- •Полиморфизм
- •Раннее связывание.
- •Позднее связывание.
- •Конструкторы и деструкторы.
- •Элементы графического интерфейса
- •Различия между консольными и графическими приложениями
- •Визуальное программирование в среде Lazarus
- •Создание графического приложения
- •Форма и ее основные свойства
- •Компоненты
- •Обработчики событий
- •Простейшие компоненты
- •6.3.5.1. Компонент TLabel
- •6.3.5.2. Кнопки TButton, TBitBtn и TSpeedButton
- •6.3.6.1. Компонент TEdit
- •6.3.6.2. Компонент TLabeledEdit
- •6.3.7.1. Компонент TMaskEdit
- •Специальные компоненты для ввода чисел
- •Тестирование и отладка программы
- •Компоненты отображения и выбора данных
- •6.3.10.1. Компонент TMemo
- •6.3.10.2. Компонент TStringGrid
- •6.3.10.3. Компоненты выбора
- •Компонент TListBox
- •Компонент TComboBox
- •Компоненты выбора – переключатели
- •6.3.10.4. Компоненты отображения структурированных данных
- •Компонент TTreeView
- •Компонент TListView
- •Организация меню. Механизм действий - Actions
- •6.3.11.1. Компонент TMainMenu
- •6.3.11.2. Компонент TToolBar
- •6.3.11.3. Компонент TActionList
- •6.3.11.4. Создание приложений с изменяемыми размерами окон
- •Послесловие
- •Литература
- •Алфавитный указатель
Глава 4 Типовые алгоритмы обработки
информации
К типовым алгоритмам я отношу алгоритмы сортировки, поиска и алго-
ритмы работы с динамическими структурами. Можно, конечно, рассмотреть и множество других алгоритмов, отнеся их к типовым. Но мы данной главе рас-
смотрим именно эти алгоритмы.
4.1. Алгоритмы сортировки
Сортировка - процесс упорядочения элементов какого-либо объекта по возрастанию или убыванию значений выбранного признака. По окончании сор-
тировки элементы располагаются либо по возрастанию, либо по убыванию. Ес-
ли среди элементов имеются одинаковые, то говорят сортировка по неубыва-
нию или по невозрастанию. На сортировку информации тратится 25-50% ма-
шинного времени при работе со сложными программными комплексами (раз-
личные информационно-поисковые системы на базе СУБД, компиляторы и другие программные средства).
Сортировать можно данные, для которых определены операции сравнения.
Чаще всего сортировке подлежат числа. Однако сортировать можно не только числа как таковые. Мы с вами уже знаем, что символы представляются в памя-
ти в виде некоторых кодов. Таким образом, вполне можно сортировать симво-
лы, например, фамилии можно отсортировать по алфавиту. Сортировать можно не только объекты, содержащие одиночные элементы, но и объекты достаточно сложной структуры, например записи, содержащие несколько элементов. Фай-
лы, как правило, содержат записи сложной структуры. Таким
272
Глава 4 Типовые алгоритмы обработки информации
____________________________________________________________________
образом и в основном, сортировке подлежат файлы. В программе предыдущего раздела структура записи файла состояла из нескольких полей, таких как "Фа-
милия", "Группа", "Предмет", "Оценка". Вполне можно осуществить сортиров-
ку этого файла, например по группе, а внутри группы отсортировать фамилии студентов по алфавиту. Поле, по которому осуществляется сортировка называ-
ется ключом. В нашем случае ключ это сначала поле "Группа", затем поле "Фа-
милия" внутри отсортированной части файла, соответствующей той или иной группе.
Эффективность методов сортировки оценивается по числу сравнений эле-
ментов между собой и числу перестановок элементов для упорядочения масси-
ва или файла. Существуют огромное количество алгоритмов сортировки. Если сортируемый файл полностью помещается в оперативной памяти, то сортиров-
ка называется внутренней. Сортировка файлов на диске называется внешней сортировкой. Кроме того, все алгоритмы сортировки можно условно разделить на "простые", но "медленные" и "сложные", но "быстрые". Взятие в кавычки здесь не случайно. В некоторых случаях "сложные", но "быстрые" алгоритмы оказываются медленнее "простых". Чаще всего так происходит для небольших файлов. Для подавляющего числа случаев "простые" алгоритмы вполне подхо-
дят по скорости работы и нет смысла "извращаться", пытаясь реализовать сложные и хитроумные алгоритмы. Необходимо помнить, что чем проще алго-
ритм (и это относится не только к алгоритмам сортировки), тем надежнее будет работать ваша программа. И только для очень больших файлов, когда именно на сортировке ваша программа "застревает", стоит поискать более сложные и быстрые алгоритмы.
Рассмотрим несколько алгоритмов сортировки. В примерах мы будем рас-
сматривать сортировку массивов целых чисел.
273
4.1 Алгоритмы сортировки
____________________________________________________________________
4.1.1 Обменная сортировка (метод "пузырька")
Свое название алгоритм получил благодаря тому, что в процессе сортиров-
ки меньшие (большие) числа как бы всплывают вверх как пузырьки воздуха в воде. Если идет сортировка по возрастанию, "всплывают" меньшие числа, если
по убыванию, то большие. Рассмотрим пример.
Пусть имеется массив, состоящий из четырех чисел: 4, 3, 2, 1. Необходимо
расположить элементы массива по возрастанию. Сравниваются, начиная с кон-
ца массива пары соседних чисел. Если они расположены в неправильном по-
рядке – меняем их местами. В результате первого прохода наименьший элемент
(число 1) оказывается "наверху", на месте нулевого элемента, т.е. самый "лег-
кий" элемент "всплыл на поверхность", рис. 4.1.
4 |
4 |
4 |
1 |
3 |
3 |
1 |
4 |
2 |
1 |
3 |
3 |
1 |
2 |
2 |
2 |
Рис. 4.1 Состояние массива во время первого прохода.
Как видно из рисунка, на первом шаге текущего прохода меняются мес-
тами числа "1" и "2". На втором шаге меняются "1" и "3" и на четвертом шаге
меняются местами "1" и "4".
Далее осуществляется второй проход, в котором просматриваются элемен-
ты массива, кроме первого, который уже "встал" на свое место. Состояние мас-
сива во время второго прохода, рис. 4.2: |
|
||||
|
|
|
|
||
|
1 |
|
1 |
|
1 |
4 |
4 |
2 |
|||
3 |
2 |
4 |
|||
2 |
3 |
3 |
Рис. 4.2 Состояние массива во время второго прохода.
274
Глава 4 Типовые алгоритмы обработки информации
____________________________________________________________________
На рисунке элемент, который уже не участвует в просмотре, выделен.
На следующем (последнем для данного массива) проходе поменяются мес-
тами числа "4" и "3". В итоге получаем отсортированный массив:
1 |
|
1 |
2 |
|
2 |
4 |
3 |
|
3 |
4 |
Рис. 4.3 После третьего прохода получаем отсортированный массив.
Таким образом, проходы делаются по все уменьшающейся нижней части массива до тех пор, пока в ней не останется только один элемент. На этом сор-
тировка заканчивается, так как последовательность упорядочена по возраста-
нию. Блок-схема алгоритма сортировки методом "пузырька" приведена на ри-
сунке 4.4.
Составим программу с использованием динамических массивов. При раз-
боре программы не забудьте, что индексация элементов в таких массивах начи-
нается с 0!
program bubble_sort; uses
CRT, FileUtil; var
i, n: integer;
vector: array of integer;
{ ============= Сортировка методом "пузырька" ======== } procedure bubble(var vector: array of integer); var
temp: integer;
i, j, count: integer; begin
275
4.1 Алгоритмы сортировки
____________________________________________________________________
начало
Ввод массива x
|
|
|
|
|
i=2 |
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
j=n |
|
||
нет |
|
|
|
|
|
|
||
|
x j 1 |
x j |
|
|||||
|
|
|
|
|
||||
|
|
|
|
|||||
|
|
|
|
|
|
|
|
да |
|
|
|
|
|
|
|
|
|
|
|
b |
|
x j |
1 |
|
|
|
|
|
x j |
1 |
x j |
||||
|
|
x j |
|
b |
|
|
|
|
|
|
|
|
|
|
|
|
|
j=j-1
да
j i
нет
i=i+1
да
i n
нет
Вывод отсортированного массива x
конец
Рис. 4.4 Блок-схема алгоритма сортировки методом "пузырька".
count:= high(vector); for i:= 1 to count do for j:= count downto i do
if vector[j - 1] > vector[j] then begin
temp:= vector[j - 1]; vector[j - 1]:= vector[j]; vector[j]:= temp;
end
276
Глава 4 Типовые алгоритмы обработки информации
____________________________________________________________________
end;
begin
writeln(UTF8ToConsole('Введите количество элементов массива'));
readln(n);
SetLength(vector, n );
writeln(UTF8ToConsole('Введите '), n);
writeln(UTF8ToConsole('значений элементов массива')); for i:= 0 to n - 1 do read(vector[i]); bubble(vector);
writeln;
writeln(UTF8ToConsole('Отсортированный массив')); for i:= 0 to n - 1 do write(vector[i], ' '); writeln;
writeln(UTF8ToConsole('Нажмите любую клавишу')); readkey;
end.
Алгоритм пузырьковой сортировки является одним из самых медленных. В
реализации алгоритма имеются два цикла. При первом выполнении внутренне-
го цикла будет выполнено n-1 сравнений, при втором n-2 сравнений и т.д. Всего будет выполнено n-1 таких циклов. Таким образом, всего будет выполнено
(n-1) + (n-2) + … + 1
сравнений. Выражение можно упростить: n(n-1)/2 или (n2- n)/2
Таким образом, пузырьковая сортировка требует O(n2) сравнений. Количе-
ство перестановок для самого худшего случая, когда элементы массива отсор-
тированы в обратном порядке равно количеству сравнений, т.е. O(n2).
Имеется возможность небольшого улучшения алгоритма. Если во внут-
реннем цикле не происходит ни одной перестановки, то это означает, что мас-
сив уже отсортирован и дальнейшее выполнение алгоритма можно прекратить.
277
4.1 Алгоритмы сортировки
____________________________________________________________________
В наилучшем случае, когда входной массив уже отсортирован, алгоритму тре-
буется всего (n-1) сравнений и ни одной перестановки. К сожалению, в наи-
худшем случае, когда все элементы массива расположены в обратном порядке,
выигрыша во времени исполнения алгоритма не происходит. Приведем все-
таки реализацию этой модификации метода:
program modify_bubble_sort; uses
CRT, FileUtil; var
i, n: integer;
vector: array of integer;
{ ============= Сортировка методом "пузырька" ======== } procedure bubble(var vector: array of integer); var
temp: integer;
i, j, count: integer; perestanovka: boolean = false;
begin
count:= high(vector); for i:= 1 to count do begin
for j:= count downto i do
if vector[j - 1] > vector[j] then begin
perestanovka:= true; temp:= vector[j - 1]; vector[j - 1]:=vector[j]; vector[j]:= temp;
278