
- •Введение
- •Основные понятия и определения
- •Типы данных
- •1.1.1. Понятие типа данных
- •1.2.2. Внутреннее представление базовых типов в оперативной памяти
- •1.2.2. Внутреннее представление структурированных типов данных
- •1.2.3. Статическое и динамическое выделение памяти
- •Абстрактные типы данных (атд)
- •Понятие атд
- •1.2.2. Спецификация и реализация атд
- •Структуры данных
- •1.3.1. Понятие структуры данных
- •1.3.2. Структуры хранения — непрерывная и ссылочная
- •1.4.3. Классификация структур данных
- •Алгоритмы
- •1.4.1. Понятие алгоритма
- •1.4.2. Способы записи алгоритмов.
- •1.4.3. Введение в анализ алгоритмов Вычислительные модели
- •Задача анализа алгоритмов
- •Время работы алгоритма
- •Время выполнения в худшем и среднем случае
- •1.4.3. Введение в рекурсию
- •Первые примеры
- •1.5.1. Введение в «длинную» арифметику
- •1.5.2. Рекурсия
- •1.5.3. Поразрядные операции. Реализация атд «Множество»
- •2. Линейные структуры данных
- •2.1. Атд "Стек", "Очередь", "Дек"
- •2.2. Реализация стеков
- •2.2.1. Непрерывная реализация стека с помощью массива
- •2.2.2. Ссылочная реализация стека в динамической памяти
- •2.2.3. Примеры программ с использованием стеков
- •2.3. Реализация очередей
- •2.3.2. Непрерывная реализация очереди с помощью массива
- •2.3.2. Ссылочная реализация очереди в динамической памяти
- •2.3.3. Ссылочная реализация очереди с помощью циклического списка
- •2.3.4. Очереди с приоритетами
- •2.3.5. Пример программы с использованием очереди
- •2.4. Списки как абстрактные типы данных
- •2.4.1. Модель списка с выделенным текущим элементом
- •2.4.2. Однонаправленный список (список л1)
- •2.4.3. Двунаправленный список (список л2)
- •2.4.4. Циклический (кольцевой) список
- •2.5. Реализация списков с выделенным текущим элементом
- •2.5.1. Однонаправленные списки Ссылочная реализация в динамической памяти на основе указателей
- •2.5.2. Двусвязные списки
- •2.5.3. Кольцевые списки
- •2.5.4. Примеры программ, использующих списки Очередь с приоритетами на основе линейного списка
- •Задача Иосифа (удаление из кольцевого списка)
- •2.6. Рекурсивная обработка линейных списков
- •2.6.1. Модель списка при рекурсивном подходе
- •2.6.2. Реализация линейного списка при рекурсивном подходе
- •3. Иерархические структуры данных
- •3.1. Иерархические списки
- •3.1.1 Иерархические списки как атд
- •3.1.2. Реализация иерархических списков
- •3.2. Деревья и леса
- •3.2.1. Определения
- •3.2. Способы представления деревьев
- •3.2.3. Терминология деревьев
- •3.2.4. Упорядоченные деревья и леса. Связь с иерархическими списками
- •3.3. Бинарные деревья
- •3.3.1. Определение. Представления бинарных деревьев
- •3.3.2. Математические свойства бинарных деревьев
- •3.4. Соответствие между упорядоченным лесом и бинарным деревом
- •3.5. Бинарные деревья как атд
- •3.6. Ссылочная реализация бинарных деревьев
- •3.6.1. Ссылочная реализация бинарного дерева на основе указателей
- •3.6.2. Ссылочная реализация на основе массива
- •3.6.3. Пример — построение дерева турнира
- •3.7. Обходы бинарных деревьев и леса
- •3.7.1. Понятие обхода. Виды обходов
- •3.7.2. Рекурсивные функции обхода бинарных деревьев
- •3.7.3. Нерекурсивные функции обхода бинарных деревьев
- •3.7.4. Обходы леса
- •3.7.5. Прошитые деревья
- •3.8. Применения деревьев
- •3.8.1. Дерево-формула
- •3.8.2. Задача сжатия информации. Коды Хаффмана
- •4. Сортировка и родственные задачи
- •4.1. Общие сведения
- •4.1.1. Постановка задачи
- •4.1.2. Характеристики и классификация алгоритмов сортировки
- •4.2. Простые методы сортировки
- •4.2.1. Сортировка выбором
- •4.2.2. Сортировка алгоритмом пузырька
- •4.2.3.Сортировка простыми вставками.
- •4.3. Быстрые способы сортировки, основанные на сравнении
- •4.3.1. Сортировка упорядоченным бинарным деревом
- •Анализ алгоритма сортировки бинарным деревом поиска
- •4.3.2. Пирамидальная сортировка
- •Первая фаза сортировки пирамидой
- •Вторая фаза сортировки пирамидой
- •Анализ алгоритма сортировки пирамидой
- •Реализация очереди с приоритетами на базе пирамиды
- •4.3.2. Сортировка слиянием
- •Анализ алгоритма сортировки слиянием
- •4.3.3. Быстрая сортировка Хоара
- •Анализ алгоритма быстрой сортировки
- •4.3.4. Сортировка Шелла
- •4.3.5. Нижняя оценка для алгоритмов сортировки, основанных на сравнениях
- •4.4. Сортировка за линейное время
- •4.4.1. Сортировка подсчетом
- •4.4.2. Распределяющая сортировка от младшего разряда к старшему
- •4.4.3. Распределяющая сортировка от старшего разряда к младшему
- •5. Структуры и алгоритмы для поиска данных
- •5.1. Общие сведения
- •5.1.1. Постановка задачи поиска
- •5.1.2. Структуры для поддержки поиска
- •5.1.3. Соглашения по программному интерфейсу
- •5.2. Последовательный (линейный) поиск
- •5.3. Бинарный поиск в упорядоченном массиве
- •5.4. Бинарные деревья поиска
- •5.4.1. Анализ алгоритмов поиска, вставки и удаления Поиск
- •Вставка
- •Удаление
- •5.4.3. Реализация бинарного дерева поиска
- •5.5. Сбалансированные деревья
- •Определение и свойства авл-деревьев
- •Вращения
- •Алгоритмы вставки и удаления
- •Реализация рекурсивного алгоритма вставки в авл-дерево
- •5.5.2. Сильноветвящиеся деревья
- •Бинарные представления сильноветвящихся деревьев
- •5.5.3. Рандомизированные деревья поиска
- •5.6. Структуры данных, основанные на хеш-таблицах
- •5.6.2. Выбор хеш-функций и оценка их эффективности
- •Модульное хеширование (метод деления)
- •Мультипликативный метод
- •Метод середины квадрата
- •5.6.2. Метод цепочек
- •5.6.3. Хеширование с открытой адресацией
- •5.6.4. Пример решения задачи поиска с использованием хеш-таблицы
2.4. Списки как абстрактные типы данных
2.4.1. Модель списка с выделенным текущим элементом
Будем считать, что состояние списка задается не только перечислением набора элементов, но и дополнительно указанием одного из них в качестве текущего элемента. Относительно этого элемента будет определяться семантика базовых операций. Заданием текущего элемента список разделяется на две части: от начала до текущего элемента (пройденная или прочитанная часть) и от текущего элемента (включая его) до конца списка (рис.2.9). К элементам пройденной части можно получить доступ, только начиная просмотр списка с начала. В непройденной части доступны все элементы поочередно, начиная с текущего элемента.
Рис.2.9. Модель списка с текущим элементом
Набор операций над списками существенно расширен по сравнению со стеками или очередями. В первую очередь это касается операций вставки и удаления — их теперь можно выполнять не только на концах, но в любой позиции списка, в зависимости от положения текущего элемента.
Операция вставки неформально определяется так — вставить элемент перед текущим, при этом текущим должен стать новый элемент. Особый случай вставки — новый элемент добавляется в конец списка.
При удалении текущего элемента следующий становится текущим. Нельзя удалять из пустого списка.
Одна из часто выполняемых операций над списками — получение значения текущего элемента. Можно выделить отдельную операцию изменения значения текущего элемента. Хотя ее можно представить как последовательность из двух операций (удаления с последующей вставкой), это будет неудобно в реализации.
Для любых списков требуются дополнительные операции создания пустого списка и проверки списка на наличие в нем хотя бы одного элемента.
Поскольку все базовые операции определяются относительно текущего элемента, обязательно должна быть обеспечена возможность изменения текущего элемента, иными словами, механизм передвижения по списку. Различные виды списков отличаются друг от друга именно по возможности передвижения по списку. Определим соответствющие абстрактные типы данных.
2.4.2. Однонаправленный список (список л1)
В однонаправленном списке двигаться от элемента к элементу можно только в одном направлении. Для многих приложений этого достаточно, допустим для выполнения таких действий над списками как вычисление суммы элементов, вычисление максимального элемента, изменение значений элементов и т. д.
Для передвижения по однонаправленному списку достаточно определить такие операции:
сделать текущим первый элемент (встать в начало списка);
сделать текущим следующий элемент (продвинуться вперед на один элемент):
проверить, не достигнут ли конец списка при переходе от текущего элемента к следующему, что может случиться, если текущим был последний элемент.
2.4.3. Двунаправленный список (список л2)
В списках Л2 базовые операции также определяются относительно текущего элемента (см. рис. 2.9), поэтому основной набор операций совпадает со списками Л1. Дополнительная возможность состоит в обходе списка не только в прямом, но и обратном направлении. Такая возможность требуется, например, при реализации просмотра или редактирования текстовых файлов с использованием списков и многих других алгоритмах.
Для того, чтобы сделать возможным движение по списку в двух направлениях, необходимо добавить к тем операциям, которые определены для однонаправленного списка, еще три дополнительных операции:
сделать текущим последний элемент (встать в конец списка);
сделать текущим предыдущий элемент (продвинуться назад на один элемент):
проверить состояние начала списка при переходе к предыдущему элементу, что может случиться, если текущим был первый элемент.
Формальную спецификацию списков Л1 и Л2 можно выполнить самостоятельно по аналогии со стеками и очередями. В следующем разделе, посвященном реализации списков, формальная спецификация будет выполнена средствами языка программирования.