
- •Тема 1. Стеки, очереди, деки 7
- •Тема 2. Односвязные и двусвязные линейные списки 21
- •Тема 3. Бинарные деревья 40
- •Тема 4. Графы 65
- •Введение
- •Терминология
- •Классификация структур данных по различным признакам
- •Типовые операции над структурами данных
- •Эффективность алгоритмов. O-обозначения
- •Тема 1. Стеки, очереди, деки
- •Операции над стеком
- •Реализация стека
- •Реализация основных операций над стеком
- •Использование стека для преобразования форм записи выражений.
- •Очередь
- •Операции над очередью
- •Операции над деком
- •Реализация очереди и дека
- •Реализация основных операций над очередью и деком
- •Итератор
- •Лабораторная работа 1. Стеки, очереди, деки
- •Тема 2. Односвязные и двусвязные линейные списки
- •Линейный список
- •Операции над линейным списком
- •Реализация линейного списка в виде односвязной динамической структуры
- •Реализация основных операций над односвязным списком
- •Циклический список
- •Операции над циклическим списком
- •Односвязная реализация циклического списка
- •Реализация основных операций над односвязным циклическим списком
- •Реализация линейного списка в виде двусвязной динамической структуры
- •Реализация основных операций над двусвязным списком
- •Циклический двусвязный список
- •Реализация основных операций над двусвязным циклическим списком
- •Лабораторная работа 2. Односвязные и двусвязные линейные списки
- •Тема 3. Бинарные деревья
- •Основные понятия и определения
- •Построение бинарного дерева
- •Операции над бинарным деревом
- •Реализация бинарного дерева
- •Реализация основных операций над бинарным деревом
- •Дерево выражения
- •Дерево поиска
- •Операции над деревом поиска
- •Реализация дерева поиска
- •Реализация операций над деревом поиска
- •Сбалансированные деревья
- •Включение в сбалансированное дерево
- •Лабораторная работа 3. Бинарные деревья
- •Тема 4. Графы
- •Основные понятия и определения
- •Граф g7
- •Операции над графом
- •Реализация графа
- •Реализация основных операций над ориентированным графом
- •Обход ориентированного графа
- •Вычисление расстояния между узлами ориентированного графа
- •Лабораторная работа 4. Ориентированные графы
- •Библиографический список
-
Вычисление расстояния между узлами ориентированного графа
Напомним, что расстоянием между двумя узлами n1 и n2 называется длина кратчайшего пути между этими узлами. Очевидно, что представляет интерес не только значение расстояния между двумя узлами, но и перечень узлов, входящих в кратчайший путь. Для решения этой задачи необходимо переопределить тип tNode, включив в него дополнительные поля: Dist – расстояние до данного узла от некоторого другого узла, PrevNode – указатель на узел, предшествующий текущему в кратчайшем пути. Начальное значение поля Dist для всех узлов равно нулю. Определяем расстояния от узла n1 до всех остальных узлов графа, для чего последовательно обходим граф от узла n1 по спискам смежности и в поле Dist узла, являющегося концом очередной дуги, записываем значение, равное сумме уже вычисленного расстояния до начального узла дуги плюс 1. Изменять значение поля Dist конечного узла дуги надо только в том случае, если оно меньше того значения, которое в этом поле хранится (расстояние – длина кратчайшего пути до узла). При каждом изменении значения поля Dist необходимо переопределять значение поля PrevNode, записывая в него указатель на тот узел, длина пути от которого до текущего узла оказалась меньшей.
Дополнительно необходимо хранить сведения об уже пройденных узлах (можно использовать поле Visited логического типа), чтобы не посещать их повторно. Начальное значение этого поля для всех узлов равно False. В основе алгоритма вычисления кратчайшего пути между узлами n1 и n2 лежит рекурсивный обход графа в глубину.
Метод tOrGraph.SPath возвращает строку с перечнем информационных полей узлов графа (типа tValue=Char), входящих в кратчайший путь между узлами Node1 и Node2. Длина кратчайшего пути (расстояние) равна длине этой строки, уменьшенной на 1.
function tOrGraph.SPath(Node1,Node2:pNode):String;
// Кратчайший путь между узлами Node1 и Node2
procedure PathFromNode(Node:pNode);
// Внутренняя рекурсивная процедура
// вычисления расстояния от узла Node до всех узлов графа
var
Arc:pArc; // дуга графа
NextNode:pNode; // узел графа, следующий за Node
begin
Node^.Visited:=True; // отметка о посещении узла Node
Arc:=Node^.ArcList; // указатель на список смежности узла Node
while Arc<>nil do begin // пока не исчерпан список смежности узла Node
NextNode:=Arc^.RearNode; // узел, смежный с узлом Node
if not NextNode^.Visited
then begin // если узел NextNode еще не посещался,
NextNode^.Dist:=Node^.Dist+1; // то расстояние до него равно 1,
PathFromNode(NextNode); // продолжаем обход от него
NextNode^.PrevNode:=Node; // предыдущий узел для NextNode - Node
end
else // если узел NextNode уже посещался и,
if Node^.Dist+1<NextNode^.Dist // длина пути к нему через узел Node меньше
then begin
NextNode^.Dist:=Node^.Dist+1; // то изменяем длину пути на меньшую и
NextNode^.PrevNode:=Node; // запоминаем узел, через который пришли
end;
Arc:=Arc^.NextArc; // переход к следующей дуге списка смежности
end;
end; // procedure PathFromNode
var
Node:pNode; // текущий узел графа
S:string; // строка – перечень узлов кратчайшего пути
begin
Node:=fHead;
// установка начальных значений всех узлов графа
while Node<>nil do begin
Node^.Visited:=False; Node^.Dist:=0;
Node:=Node^.NextNode;
end;
// вычисление расстояний от узла Node1 до всех остальных
PathFromNode(Node1);
Node:=Node2; s:=NodeValue(Node2); // включение Node2 в начало строки
while Node<>Node1 do begin
// для всех узлов в кратч. пути от Node2 до Node1
Node:=Node^.PrevNode; // переход к узлу, предшествующему Node2
Insert(NodeValue(Node),S,1); // включение предш. узла в начало строки
end;
SPath:=S;
end; // function tOrGraph.SPath
Если значение, хранящееся в узле графа, имеет тип, отличный от Char, то можно хранить кратчайший путь в виде списка.