- •Оглавление
- •Введение
- •Раздел 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. Контрольные вопросы по теме
- •Основные термины и понятия
- •Литература
2.5. Динамическая реализация очереди
Аналогично стеку, каждый элемент очереди должен иметь ссылку на следующий за ним элемент, поэтому элемент очереди объявляется как запись с двумя полями – информационное поле и связующее поле. Но для реализации операций с очередью необходимы уже две переменные: указатель pFirst на начало очереди и указатель pLast на конец очереди.
Приведенная ниже схема элементов очереди отражает логический порядок следования элементов, физически же элементы могут находиться в любых свободных областях памяти.
эл-т
1 next
: 2
эл-т
2 next
: 3
эл-т
3 next
: 4
эл-т
N nil
. . . . . . . .
pFirst pLast
Основные операции с динамической очередью:
проверка отсутствия элементов в очереди
добавление нового элемента в конец очереди
удаление элемента из начала очереди
проход по очереди от начала к концу
Добавление нового элемента немного по-разному реализуется для пустой и непустой очереди. Аналогично, по-разному выполняется удаление из очереди, содержащей один или более одного элемента. Для того, чтобы эти операции во всех случаях выполнялись единообразно, часто используется следующий прием: в начало очереди вводится фиктивный элемент-заголовок, который НИКОГДА не удаляется и всегда содержит адрес первого элемента очереди.
В этом случае создание пустой очередивключает в себя:
выделение памяти для заголовка с помощью указателя pFirst
занесение в ссылочную часть заголовка пустого указателя nil
установка указателя конца очереди pLast = pFirst
Схемы пустой и непустой очереди приводятся на следующих рисунках:
заголовок nil
заголовок Next:
1
элем.
1 Next:
2
элем.
N nil
…..
pFirst pLast pFirst pLast
Необходимые описания типов и переменных:
type pQueueItem = ^ TQueueItem;
{Ссылочный тип для адресации элементов очереди}
TQueueItem = record {базовый тип: структура элемента очереди}
inf : integer; {информационная часть}
next : pQueueItem;
{ссылочная часть: адрес следующего элемента}
end;
var pFirst, pLast : pQueueItem;
Тогда условие пустой очереди можно записать следующим образом:
pFirst^.next = nil
Для прохода по очередиот первого реального элемента к последнему необходимо:
ввести вспомогательную ссылочную переменную pTemp
установить pTemp в адрес первого реального элемента: pTemp := pFirst^.next
организовать цикл по условию достижения конца очереди
в цикле обработать очередной элемент с помощью указателя pTemp и изменить этот указатель: pTemp := pTemp^.next
Добавление элемента в конец очереди выполняется следующим образом:
выделить память для нового элемента с помощью стандартной функции New и вспомогательной ссылочной переменнойpTemp:
заполнить поля нового элемента, в частности в связующую часть установить значение nil:pTemp^.next:= nil
изменить связующую часть бывшего последнего элемента таким образом, чтобы она адресовала новый добавленный элемент: pLast^.next:=pTemp;
изменить значение указателя pLastтак, чтобы он указывал новый последний элемент:pLast:=pTemp;
элем.
1 next: 2
элем.
N next:
n+1
новый
элем. nil
заголовок next: 1
pLast pTemp pFirst
Удаление элементаиз начала очереди (но после заголовка!) выполняется следующим образом:
адресуем удаляемый элемент с помощью вспомогательной переменной pTemp :pTemp:=pFirst^.next;
изменить связующую часть заголовка так, чтобы она указывала на второй элемент очереди, который теперь должен стать первым: pFirst^.next:=pTemp^.next
если после удаления в списке не остаётся реальных элементов, то необходимо изменить указатель pLast:pLast:=pFirst
обработать удаленный элемент, например - освободить занимаемую им память с помощью стандартной подпрограммы Dispose (pTemp) или включить его во вспомогательную очередь удаленных элементов
заголовок next: 1
элем.
1 next: 2
элем.
2 next: 3
элем.
N next:
nil
pFirst pTemp pLast
Сравнение двух способов реализации очереди полностью аналогично стеку. Интересной разновидностью очереди являются приоритетные очереди, в которых элементы выстраиваются не только в порядке поступления, но и в соответствии с их приоритетами: сначала идут более приоритетные элементы, потом – все менее приоритетные. Одноприоритетные элементы располагаются в порядке поступления. Это требует изменения процедуры добавления элемента в очередь: надо прежде всего найти место в очереди, куда должен вставиться новый элемент в соответствии с его приоритетом, а потом уже выполнить саму вставку. Фактически, приоритетную очередь можно рассматривать как разновидность упорядоченного линейного списка. Реализация линейных списков подробно рассматривается в следующей теме.