| Тип данных boolean является |
Алгоритмы на графах и деревьях
Прямой обход произвольного связного графа
Для простоты изложения будем считать, что граф задан матрицей смежности, которая хранится в квадратном массиве sm. Дополнительный линейный массив mark хранит информацию о последовательности посещения вершин:
procedure preorder_graph(v: byte);
var i: byte;
begin
k:= k+1;
mark[v]:= k; {текущей вершине v присвоен порядковый номер}
for i:= 1 to n do
if (mark[i]=0)and(sm[v,i]=1) {есть ребро из текущей вершины v
в еще не помеченную вершину i}
then preorder_graph(i);
end;
begin
...
k:= 0;
preorder_graph(start); {Вызов из тела программы}
...
end.Обратный обход
Другие названия
Постфиксный обход: результатом обратного обхода ДСА арифметического выражения будет постфиксный вариант записи этого выражения.
Обход в глубину "снизу вверх": название имеет смысл лишь в случае стандартного расположения дерева корнем кверху.
Алгоритм PostOrder
- Начать с корня дерева.
- Совершить обратный обход левого поддерева.
- Совершить обратный обход правого поддерева.
- Пометить текущую вершину.
Замечание: Этот алгоритм также может быть распространен на случай произвольного корневого дерева.
Реализация
procedure postorder(p:ukaz; k:integer);
begin if p^.left<>nil then postorder(p^.left,k+1);
if p^.right<>nil then postorder(p^.right,k+1)
p^.mark:=k;
end;
begin
...
postorder(root,1); {Вызов из тела программы}
...
end.Обратный обход произвольного связного графа
Для простоты изложения будем считать, что граф задан матрицей смежности, которая хранится в квадратном массиве sm. Дополнительный линейный массив mark хранит информацию о последовательности обхода вершин, а массив posesh - о фактах их посещения:
procedure postorder_graph(v:byte);
var i: integer;
begin
posesh[v]:=1; {текущая вершина v стала посещенной}
for i:=1 to n do
if (posesh[i]=0)and(sm[v,i]=1) {есть ребро из текущей вершины v
в еще не помеченную вершину i}
then postorder_graph(i);
inc(k);
mark[v]:=k; {текущей вершине v
присвоен порядковый номер}
end;
begin
...
k:=0;
postorder_graph(start); {вызов из тела программы}
...
end.Синтаксический обход
Другие названия
Инфиксный обход: результатом синтаксического обхода ДСА арифметического выражения будет инфиксный вариант записи этого выражения.
Обход "слева направо": название имеет смысл лишь в случае стандартного расположения дерева корнем кверху.
Алгоритм SyntOrder
- Начать с корня дерева.
- Совершить прямой обход левого поддерева.
- Пометить текущую вершину.
- Совершить прямой обход правого поддерева.
Замечание: Этот обход специфичен только для бинарных деревьев, поэтому невозможно применить его к произвольному графу, каркасом которого совершенно не обязательно будет именно бинарное дерево.
Реализация
procedure syntorder(p:ukaz; k:integer);
begin if p^.left<>nil then syntorder(p^.left,k+1);
p^.mark:=k;
if p^.right<>nil then syntorder(p^.right,k+1);
end;
begin
...
syntorder(root,1); {Вызов из тела программы}
...
end.
