- •Оглавление
- •Введение
- •Раздел 1. Основные структуры данных
- •Тема 1. Введение в структуры данных. Динамическое распределение памяти
- •Классификация структур данных
- •1.2. Переменные-указатели и динамическое распределение памяти.
- •Например, указатели на простейшие базовые типы вводятся следующим образом:
- •Var pStr1,pStr2 :TpString; {переменные-указатели на строки}
- •1.3. Дополнительные вопросы использования переменных-указателей
- •1.4. Контрольные вопросы по теме
- •Тема 2. Структуры данных “стек” и “очередь”
- •2.1. Что такое стек и очередь?
- •2.2. Статическая реализация стека
- •2.3. Динамическая реализация стека
- •{Ссылочный тип для адресации элементов стека}
- •2.4. Статическая реализация очереди
- •2.5. Динамическая реализация очереди
- •{Ссылочный тип для адресации элементов очереди}
- •2.6. Практические задания
- •2.7. Контрольные вопросы по теме
- •Тема 3. Основы реализации списковых структур
- •3.1. Структуры данных типа “линейный список”
- •3.2. Первый способ статической реализации списка.
- •3.3. Второй способ статической реализации списка.
- •3.4. Управление памятью при статической реализации списков
- •3.5. Динамическая реализация линейных списков
- •3.6. Практические задания
- •3.7. Контрольные вопросы по теме
- •Тема 4. Усложненные списковые структуры
- •4.1. Двунаправленные линейные списки
- •4.2. Комбинированные структуры данных: массивы и списки указателей
- •4.3. Комбинированные структуры данных: массивы и списки списков
- •4.4. Практические задания.
- •4.5. Контрольные вопросы по теме
- •Тема 5. Основные понятия о древовидных структурах
- •5.1. Основные определения
- •5.2. Двоичные деревья
- •5.3. Идеально сбалансированные деревья
- •5.4. Практические здания
- •5.5. Контрольные вопросы по теме
- •Тема 6. Реализация поисковых деревьев
- •Двоичные деревья поиска.
- •6.2. Добавление вершины в дерево поиска
- •6.3. Удаление вершины из дерева поиска
- •6.4. Практические задания
- •Контрольные вопросы по теме
- •Тема 7. Дополнительные вопросы обработки деревьев. Графы.
- •Проблемы использования деревьев поиска
- •7.2. Двоичные деревья с дополнительными указателями
- •7.3. Деревья общего вида (не двоичные).
- •Представление графов
- •Практические задания
- •Контрольные вопросы по теме
- •Раздел 2. Алгоритмы сортировки и поиска
- •Тема 1. Классификация методов. Простейшие методы сортировки
- •1.1. Задача оценки и выбора алгоритмов
- •1.2. Классификация задач сортировки и поиска
- •1.3. Простейшие методы сортировки: метод обмена
- •1.4. Простейшие методы сортировки: метод вставок
- •1.5. Простейшие методы сортировки: метод выбора
- •1.6. Практическое задание
- •1.7. Контрольные вопросы по теме
- •Тема 2. Улучшенные методы сортировки массивов
- •2.1. Метод Шелла
- •2.2. Метод быстрой сортировки
- •2.3. Пирамидальная сортировка
- •2.4. Практическое задание
- •2.5. Контрольные вопросы по теме
- •Тема 3. Специальные методы сортировки
- •3.1. Простейшая карманная сортировка.
- •3.2. Карманная сортировка для случая повторяющихся ключей
- •3.3. Поразрядная сортировка
- •3.4. Практическое задание
- •3.5. Контрольные вопросы по теме
- •Тема 4. Поиск с использованием хеш-функций
- •4.1. Основные понятия
- •4.2. Разрешение конфликтов: открытое хеширование
- •4.3. Разрешение конфликтов: внутреннее хеширование
- •4.4. Практические задания
- •4.5. Контрольные вопросы по теме
- •Тема 5. Внешний поиск и внешняя сортировка
- •5.1. Особенности обработки больших наборов данных
- •5.2. Организация внешнего поиска с помощью б-деревьев.
- •5.4. Поиск элемента в б-дереве.
- •5.5. Добавление вершины в б-дерево
- •5.6. Удаление вершины из б-дерева
- •5.7. Внешняя сортировка
- •5.8. Практические задания
- •5.9. Контрольные вопросы по теме
- •Основные термины и понятия
- •Литература
3.7. Контрольные вопросы по теме
В чем состоит отличие списковых структур от стека и очереди?
Что включает в себя стандартный набор операций со списком?
В чем состоит простейший способ реализации списка с помощью массива?
Как выполняется вставка элемента при простейшей реализации списка на базе массива?
Как выполняется удаление элемента при простейшей реализации списка на базе массива?
В чем состоят преимущества и недостатки простейшего способа реализации списков с помощью массивов?
За счет чего можно повысить эффективность простейшей реализации списка с помощью массива?
В чем смысл реализации статического списка с указателями-индексами?
Какую структуру имеют элементы массива при статической реализации списка?
Какие описания необходимы для статической реализации списка?
Как выполняется проход по статическому списку?
Как выполняется поиск элемента в статическом списке?
Какие особые ситуации возможны при статической реализации списка?
Что такое пустой статический список?
Как выполняется добавление элемента после заданного в статическом списке?
Как выполняется добавление элемента перед заданным в статическом списке?
Как выполняется удаление элемента в статическом списке?
Как в простейшем случае можно отслеживать свободные ячейки массива при реализации статического списка?
В чем недостатки простейшего способа отслеживания свободных ячеек при реализации статического списка?
Как используется вспомогательный список свободных ячеек при статической реализации списка?
Как инициализируется вспомогательный список свободных ячеек при создании пустого статического списка?
Что является основой реализации динамических списков?
Какую структуру имеют элементы динамического списка?
Какие описания необходимы для реализации динамического списка?
Какие переменные используются для реализации операций с динамическими списками?
Что включает в себя создание пустого динамического списка?
Как выполняется проход по динамическому списку?
Как выполняется поиск элемента в динамическом списке?
Как выполняется удаление элемента в динамическом списке?
Как выполняется добавление элемента после заданного в динамическом списке?
Как выполняется добавление элемента перед заданным в динамическом списке?
Какие особенности возникают при обработке упорядоченных списков?
Тема 4. Усложненные списковые структуры
4.1. Двунаправленные линейные списки
Недостатком рассмотренных выше списковых структур является их однонаправленность от первого элемента к последнему. Если при обработке списков часто бывает необходимо переходить от текущего элемента к его предшественнику, то такая односторонняя организация становится неудобной. Выходом является построение двунаправленных списков, в которых каждый элемент “знает” обоих своих соседей, как левого, так и правого.
Для этого каждый элемент должен иметь не одно, а два связующих поля: указатель на элемент слева и указатель на элемент справа.
Элем.
1 правый левый
Элем.
2 правый левый
Элем.
3 правый левый
Элем.
N правый левый
. . .
А
pHead
заголовок правый левый
Элем.
1 правый левый
Элем.
2 правый левый
Элем.
N правый левый
Элем.
1 правый левый
. . .
Отметим достоинства и недостатки двунаправленных списков. Достоинство – простота перехода от текущего элемента к любому его соседу. Недостатки – увеличиваются затраты памяти и число операций на поддержку дополнительного указателя.
Двунаправленный список можно реализовать как на основе массива (причем – обеими способами), так и динамически.
В последнем случае описание структуры данных выглядит следующим образом:
type pDin2Item = ^ TDin2Item; {ссылочный тип}
TDin2Item = record {базовый тип}
inf : <тип информационной части>;
left, right : pDin2Item; {адреса соседних элементов}
end;
Если pHead есть указатель на заголовок, то пустой список создается так:
выделяется память под заголовок, адресуемая указателем pHead
оба ссылочных поля заголовка устанавливаются в адрес самого заголовка: pHead^.left := pHead; pHead^.right := pHead;
(при этом пустая ссылка nil нигде НЕ используется!)
Набор операций расширяется просмотром и поиском не только в прямом, но и в обратном направлениях. Немного изменяется условие достижения конца списка – вместо условия появления пустой ссылки надо использовать условие получения на текущем шаге адреса заголовка. Например, проход в обратном направлении реализуется так:
устанавливаем начальное значение указателя текущего элемента на последний элемент списка: pCurrent := pHead^.left;
организуем цикл прохода до достижения заголовка
while pCurrent <> pHead do pCurrent := pCurrent^.left;
У
pCurrent
Левый
сосед right left
Удаляемый
элем. right left
Правый
сосед right left
Если удаляемый элемент адресуется указателем pCurrent, то pCurrent^.left определяет адрес левого соседа, а pCurrent^.right – адрес правого соседа. Тогда необходимые изменения реализуются так:
pCurrent^.left^.right := pCurrent^.right;
pCurrent^.right^.left := pCurrent^.left;
Аналогично выполняется добавление нового элемента, например – после заданного указателем pCurrent. Пусть как обычно новый элемент определяется указателем pTemp. Тогда для вставки его в список надо настроить оба его ссылочных поля, изменить правое ссылочное поле у текущего элемента и левое ссылочное поле у его правого соседа.
текущий
элем. right left
Правый
сосед right left
новый
элем. right left
pTemp pCurrent
Необходимые присваивания (порядок следования важен!):
pTemp^.right := pCurrent^.right;
pTemp^.left := pCurrent;
pCurrent^.right^.left := pTemp;
pCurrent^.right := pTemp;
Аналогично реализуется добавление нового элемента перед заданным элементом, только вместо правого соседа обрабатывается левый сосед текущего элемента.