
- •Тема 1. Стеки, очереди, деки 7
- •Тема 2. Односвязные и двусвязные линейные списки 21
- •Тема 3. Бинарные деревья 40
- •Тема 4. Графы 65
- •Введение
- •Терминология
- •Классификация структур данных по различным признакам
- •Типовые операции над структурами данных
- •Эффективность алгоритмов. O-обозначения
- •Тема 1. Стеки, очереди, деки
- •Операции над стеком
- •Реализация стека
- •Реализация основных операций над стеком
- •Использование стека для преобразования форм записи выражений.
- •Очередь
- •Операции над очередью
- •Операции над деком
- •Реализация очереди и дека
- •Реализация основных операций над очередью и деком
- •Итератор
- •Лабораторная работа 1. Стеки, очереди, деки
- •Тема 2. Односвязные и двусвязные линейные списки
- •Линейный список
- •Операции над линейным списком
- •Реализация линейного списка в виде односвязной динамической структуры
- •Реализация основных операций над односвязным списком
- •Циклический список
- •Операции над циклическим списком
- •Односвязная реализация циклического списка
- •Реализация основных операций над односвязным циклическим списком
- •Реализация линейного списка в виде двусвязной динамической структуры
- •Реализация основных операций над двусвязным списком
- •Циклический двусвязный список
- •Реализация основных операций над двусвязным циклическим списком
- •Лабораторная работа 2. Односвязные и двусвязные линейные списки
- •Тема 3. Бинарные деревья
- •Основные понятия и определения
- •Построение бинарного дерева
- •Операции над бинарным деревом
- •Реализация бинарного дерева
- •Реализация основных операций над бинарным деревом
- •Дерево выражения
- •Дерево поиска
- •Операции над деревом поиска
- •Реализация дерева поиска
- •Реализация операций над деревом поиска
- •Сбалансированные деревья
- •Включение в сбалансированное дерево
- •Лабораторная работа 3. Бинарные деревья
- •Тема 4. Графы
- •Основные понятия и определения
- •Граф g7
- •Операции над графом
- •Реализация графа
- •Реализация основных операций над ориентированным графом
- •Обход ориентированного графа
- •Вычисление расстояния между узлами ориентированного графа
- •Лабораторная работа 4. Ориентированные графы
- •Библиографический список
-
Обход ориентированного графа
При решении многих задач, связанных с графами, необходим эффективный способ систематического обхода всех узлов и дуг графа. Известны два способа обхода графов: обход в ширину и обход в глубину (в теории графов они называются поиском в глубину и поиском в ширину).
Способ обхода в глубину DFS (от depth-first search – поиск в глубину) составляет основу многих других эффективных алгоритмов работы с графами и состоит в следующем. Обход начинается с некоторого начального узла v графа g. Для каждого узла, смежного с узлом v и не посещавшегося ранее, рекурсивно применяется поиск в глубину. Когда все узлы, которые можно достичь из узла v, посещены, поиск заканчивается. Этот способ называется поиском в глубину, поскольку поиск непосещенных узлов идет в направлении вперед (вглубь) до тех пор, пока это возможно.
Для решения этой задачи необходимо переопределить тип tNode, включив в него дополнительное поле Visited логического типа – признак посещения узла. Начальное значение этого поля для всех узлов равно False. Приведенный ниже метод tOrGraph.DFS для обхода графа в глубину содержит внутреннюю рекурсивную процедуру DFSR, выполняющую обход в глубину от заданного узла Node. Посещение узла в данном методе заключается в выводе значения его содержательного поля Value в файл f.
procedure tOrGraph.DFS(StartNode: pNode; var f: Text);
// Обход в глубину, начиная с узла StartNode,
// с выводом значений узлов в файл f
procedure DFSR(Node:pNode);
// Внутренняя рекурсивная процедура обхода в глубину от узла Node
var
Arc:pArc; // дуга графа
NextNode:pNode; // узел, следующий за узлом Node
begin
Node^.Visited:=True; // отметка узла как посещенного
Write(f,Node^.Value,' > '); // посещение узла - вывод его значения в файл f
Arc:=Node^.ArcList; // первая дуга из списка дуг, инцидентных узлу Node
while Arc<>Nil do begin // поиск всех узлов, смежных с Node
NextNode:=Arc^.RearNode; // узел, смежный с узлом Node
if not NextNode^.Visited
then DFSR(NextNode); // узел не посещен - поиск от него
Arc:=Arc^.NextArc; // переход к следующему узлу, смежному с Node
end;
end; //procedure DFSR
var
Node:pNode;
begin
Node:=fHead;
while Node<>nil do begin // отметка всех узлов графа как непосещенных
Node^.Visited:=False; Node:=Node^.NextNode;
end;
DFSR(StartNode); Writeln(f);
end; // procedure tOrGraph.DFS
Способ обхода в ширину BFS (от breadth-first search – поиск в ширину) получил свое название из-за того, что при достижении во время обхода любого узла v далее рассматриваются все узлы, смежные с узлом v. После того как посещены и отмечены все не посещенные ранее узлы, смежные с узлом v, выбирается один из этих узлов и обход в ширину начинается от него, затем процесс повторяется для оставшихся смежных с v узлов. Для реализации этого алгоритма необходимо запоминать посещенные смежные с v узлы и, рассматривая их в порядке посещения, начинать процесс посещения всех узлов, смежных с ними. Для этой цели хорошо подходит такая структура данных как очередь (действительно, посещённые узлы становятся в очередь для продолжения процесса поиска от них).
procedure tOrGraph.BFS(StartNode: pNode; var f:Text);
// Обход в ширину, начиная с узла StartNode, с выводом значений узлов в файл f
var
Arc:pArc; // дуга графа
Node,NextNode:pNode; // очередной и следующий за ним узлы графа
q:tQueue; // экземпляр очереди с элементами типа pNode
begin
Node:=fHead;
while Node<>nil do begin // отметка всех узлов графа как непосещенных
Node^.Visited:=False; Node:=Node^.NextNode;
end;
q:= tQueue.Create; // создание экземпляра очереди
StartNode^.Visited:=True; // отметка начального узла как посещенного
Write(f,StartNode^.Value,' > '); // посещение начального узла
q.Insert(StartNode); // включение элемента StartNode в конец очереди
while not q.Empty do begin // пока очередь не пуста
Node:=q.Remove; // исключение первого элемента из очереди
Arc:=Node^.ArcList; // первая дуга из списка дуг, инцидентных узлу Node
while Arc<>nil do begin // поиск всех узлов, смежных с Node
NextNode:=Arc^.RearNode; // узел, смежный с узлом Node
if not NextNode^.Visited // если смежный узел не посещен,
then begin
NextNode^.Visited:=True; // то отметка его как посещенного,
Write(f,NextNode^.Value,' > '); // посещение узла
q.Insert(NextNode); // и включение его в конец очереди
end;
Arc:=Arc^.NextArc; // переход к следующему смежному с Node узлу
end;
end;
Writeln(f); q.Free; // удаление очереди
end; // procedure BFS
Для графа
обход в глубину дает последовательность узлов A, B, C, D, E, F, обход в ширину – A, B, D, C, E, F.
Если некоторые узлы графа при поиске от начального узла остались непосещенными, то выбирается один из них и поиск повторяется. Этот процесс продолжается до тех пор, пока обходом не будут охвачены все узлы графа.