
- •Содержание
- •Рекомендации к проведению лабораторных работ
- •Комментарии в тексте программы
- •Компиляция и запуск программы на выполнение
- •Переменные и константы
- •Операторы и выражения
- •Оператор присваивания
- •Арифметические операции
- •Логические операции
- •Составной оператор begin..end
- •Условный оператор if..then
- •Оператор-селектор case..of
- •Операторы обработки циклов
- •Цикл с параметром for .. do
- •Цикл с предусловием while..do
- •Цикл с постусловием repeat..until
- •Процедуры break и continue
- •Оператор with..do
- •Процедуры и функции
- •Процедуры
- •Функции
- •1. Фундаментальные структуры данных
- •Общее понятие типа данных
- •Простой тип
- •Перечислимые типы данных
- •Поддиапазонны
- •Строковый тип
- •Структурные типы
- •Массивы
- •Записи
- •Множества
- •Представление структур в памяти
- •Задание
- •2. Работа с последовательностями, файлы
- •Доступ к файлу
- •Операции над файлами
- •Окончание файла
- •Пример работы с файлом
- •Задание
- •3. Анализ алгоритмов
- •Рост функций
- •Задание
- •4. Простейшие методы сортировки массивов
- •Оценка алгоритмов сортировки
- •Шейкер-сортировка
- •Сортировка простыми вставками
- •Сортировка бинарными вставками
- •Задание
- •5. Улучшенные методы сортировки массивов
- •Сортировка с помощью включений с уменьшающимися расстояниями (сортировка Шелла)
- •Пирамидальная сортировка
- •Сортировка с разделением (быстрая сортировка)
- •Задание
- •6. Сортировка последовательных файлов
- •Сортировка простым слиянием
- •Естественное слияние
- •Задание
- •7. Рекурсивные алгоритмы
- •Сравнение рекурсии и итерации
- •Задание
- •8. Динамические структуры данных, связные списки
- •Списки
- •Пример создания и заполнения списка
- •Задание
- •9. Нелинейные структуры данных
- •Граф
- •Бинарное дерево
- •Задание
- •10. Алгоритмы на графах
- •Алгоритмы обхода в глубину и по уровням
- •Построение минимального остовного дерева
- •Поиск кратчайшего пути
- •Задание
- •11. Поиск данных
- •Двоичный (бинарный) поиск элемента в массиве
- •Интерполяционный поиск элемента в массиве
- •Алгоритм Бойера-Мура
- •Задание
- •12. Хеширование
- •Отечественный стандарт хеширования
- •Создание хеш-функции
- •Хеш-функции для строковых значений, алгоритм Гонера
- •Задание
- •13. Методы сжатия текстовых данных
- •Метод “Running”
- •Словарные методы сжатия
- •Алгоритм Хаффмана
- •Задание
- •14. Алгоритмы вывода графических примитивов
- •Рисование отрезка
- •Прямое вычисление координат
- •Инкрементный алгоритм Брезенхэма
- •Простейший алгоритм закрашивания замкнутой области
- •Задание
- •15. Псевдослучайные последовательности
- •Метод середин квадратов
- •Линейный конгруэнтный метод
- •Генератор псевдослучайных чисел, поставляемый с системой
- •Оценка качества генератора ПСП
- •Задание
- •16. Параллельные алгоритмы
- •Пример многопоточного приложения
- •Задание
- •Задание на СКР
- •Вариант 1. Клеточные автоматы
- •Вариант 2. Раскрашивание карты
- •Вариант 3. Крисс-кросс
- •Вариант 4. Лабиринт
- •Список использованной литературы
- •Приложение A. Справочник по функциям Delphi
- •Операции с порядковыми типами
- •Математические функции и процедуры
- •Генерация псевдослучайного числа
- •Преобразование типов данных
- •Работа с памятью
- •Приложение Б. Компонент-сетка TStringGrid
- •Приложение В. Компонент-диаграмма TChart
- •Приложение Д. Элементарный поток – класс TThread

36
5. Улучшенные методы сортировки массивов
Вид занятия – лабораторная работа Цель – исследование улучшенных методов сортировки одномерных массивов
Продолжительность – 4 часа
Анализ всех простейших методов сортировки показывает, что сортировка обменом и её небольшие улучшения хуже, чем сортировка включениями или выбором. Единственное преимущество сортировки пузырьком – легко запоминающееся название. Алгоритм Шейкер-сортировки выгодно применять лишь в редких случаях (когда массив частично упорядочен).
Все рассмотренные в предыдущей работе алгоритмы относятся к классу N2. Во многом такой плохой показатель определяется тем, что простые алгоритмы на каждом шаге чаще всего перемещают элементы на одну позицию. Сегодня мы рассмотрим алгоритмы, перемещающие данные за один цикл на большее расстояние.
Сортировка с помощью включений с уменьшающимися расстояниями (сортировка Шелла)
В 1959 году Дональд Л. Шелл предложил улучшение сортировки простыми включениями. Сортировка получила название сортировки включениями с убывающим приращением или сортировки Шелла.
Сортировка Шелла представляет собой несколько этапов сортировок, каждая из которых программируется, как классическая сортировка включениями. На рисунке 5.1 представлен процесс сортировки массива из 8-ми элементов способом Шелла.
Рисунок 5.1. – Сортировка Шелла
На первом проходе отдельно группируются и сортируются элементы отстоящие друг от друга на 4 позиции. После этого элементы объединяются в группы отстоящие друг от друга на 2 позиции и сортируются заново. На 3-м проходе элементы сортируются обычной сортировкой включениями.
Сначала может показаться, что необходимость в нескольких проходах сортировки в каждом из которых участвуют все элементы, потребует больше работы чем сэкономит. Однако на каждом шаге сортировки либо участвует мало элементов, либо они уже довольно хорошо упорядочены и требуют мало перестановок.
В случае сортировки Шелла вычислительные затраты составляют N1,2.

37
Пирамидальная сортировка
Метод сортировки простым выбором основан на повторном выборе наименьшего ключа среди n элементов, затем среди n-1 элементов, и т.д. Соответственно поиск наименьшего элемента из n элементов потребует n-1 сравнений. Направление улучшения сортировки – получать от каждого прохода больше информации, чем просто указание на один наименьший элемент.
Пирамида это бинарное дерево (каждый узел которого имеет два дочерних узла) высоты k,
вкотором:
1.все узлы имеют глубину k или k-1 - дерево сбалансированное;
2.при этом уровень k-1 полностью заполнен, а уровень k заполнен слева направо;
3.выполняется "свойство пирамиды": каждый дочерний элемент меньше, либо равен родителю.
Как хранить пирамиду? Наименее хлопотно - поместить ее в массив. Соответствие между геометрической структурой пирамиды как дерева и массивом устанавливается по следующей схеме:
−в A[0] хранится корень дерева;
−левый и правый сыновья элемента A[i] хранятся, соответственно, в A[2i+1] и A[2i+2]. Схема хранения проиллюстрирована на рисунке 5.2.
[0]
44
[1] [2]
55 |
|
|
12 |
[3] |
[4] |
[5] |
[6] |
42 |
94 |
18 |
06 |
[7]
67
Рисунок 5.2.– Размещение пирамиды в массиве
Пирамидальная сортировка состоит из двух фаз:
1.Построение пирамиды (просеивание).
2.Фаза сортировки.
Начать построение пирамиды можно с A[k]...A[n], k = [size/2]. Эта часть массива удовлетворяет свойству пирамиды, так как не существует индексов i, j: i = 2i+1 (или j = 2i+2) просто потому, что такие i, j находятся за границей массива. Другими словами работа начинается с того узла, у которого имеется хотя бы один дочерний узел (см. рис. 5.3).
Далее будем расширять часть массива, обладающую столь полезным свойством, добавляя по одному элементу за шаг. Следующий элемент на каждом шаге добавления - тот, который стоит перед уже готовой частью.
Чтобы при добавлении элемента сохранялась пирамидальность, будем использовать следующую процедуру расширения пирамиды A[i+1]..A[n] на элемент A[i] влево:
1.Смотрим на сыновей слева и справа - в массиве это A[2i+1] и A[2i+2] и выбираем наибольшего из них.
2.Если этот элемент больше A[i] - меняем его с A[i] местами и идем к шагу 2, имея в виду новое положение A[i] в массиве. Иначе конец процедуры.

38
Рисунок 5.3. – Фаза просеивания элемента пирамиды
Итак, задача построения пирамиды из массива успешно решена. Как видно из свойств пирамиды,
вкорне всегда находится максимальный элемент. Отсюда вытекает алгоритм фазы 2:
1.Берем верхний элемент пирамиды A[0]...A[n] (первый в массиве) и меняем с последним местами (см. рис. 5.4). Теперь "забываем" об этом элементе и далее рассматриваем массив A[0]...A[n-1]. Для превращения его в пирамиду достаточно просеять лишь новый первый элемент.
2.Повторяем шаг 1, пока обрабатываемая часть массива не уменьшится до одного элемента.
Рисунок 5.4. – Фаза сортировки пирамиды
Очевидно, в конец массива каждый раз попадает максимальный элемент из текущей пирамиды, поэтому в правой части постепенно возникает упорядоченная последовательность.
Вычислительные затраты пирамидальной сортировки составляют N log(N) .
Сортировка с разделением (быстрая сортировка)
Сортировка с разделением, хоть и была разработана более 40 лет назад К. Хоором, является наиболее широко применяемым и одним их самых эффективных алгоритмов. Сортировка основана на том принципе, что для достижения максимальной эффективности следует производить обмены элементов на больших расстояниях.
Метод основан на подходе "разделяй и властвуй". Общая схема такова:
1.Из центральной части массива случайным образом выбираем какой-то элемент, например
X;
2.Двигаемся по массиву слева направо пока не находим элемент A[i]>X.

39
3.Двигаемся по массиву справа налево пока не находим элемент A[j]<X.
4.Элементы A[i] и A[j] меняем местами.
5.Вновь продолжаем процесс с обменом пока два просмотра не встретятся где-то в центре массива.
Врезультате массив разделится на две части, причём в левой его части будут находиться элементы меньшие X, а в правой – больше X (см. рис. 5.5).
Рисунок 5.5. – Разделение массива
После разделения массива вновь применяем механизм разделения, но на этот раз к частям массива. Процесс продолжается до тех пор, пока каждая из частей не будет состоять из одного единственного элемента.
При использовании алгоритма сортировки с разделением программисты стараются корректно выбрать медианный элемент. Медианой массива называется элемент, значение которого меньше (или равно) половины элементов массива и больше другой половины массива.
Вычислительные затраты быстрой сортировки составляют N log(N ) .
Задание
Подготовьте одномерный массив целых чисел произвольной размерности и заполните его случайными значениями.
1.Напишите три программы сортировки, используя изученные на данной лабораторной работе улучшенные методы сортировки массива.
2.Предложите алгоритм поиска медианного элемента массива для сортировки с разделением.