| Тип данных boolean является |
Алгоритмы на графах и деревьях
Построение из постфиксной записи
Для простоты предположим, что правильное арифметическое выражение подается в одной строке, без пробелов, а каждый операнд записан одной буквой. Кроме того, снова будем считать, что из записи удалены все скобки.
Алгоритм Postfix
- Если не достигнут конец строки ввода, прочитать очередной символ,если этот символ - операнд, то занести его в стек2См. лекцию 9.,иначе (символ - операция):
- создать новый элемент, записать в него эту операцию;
- достать из стека два верхних (последних) элемента, присоединить их в качестве левого и правого операндов в новый элемент;
- занести полученный "треугольник" в стек.
По окончании работы этого алгоритма в стеке будет содержаться ровно один элемент - указатель на корень построенного дерева.
Реализация
Для того чтобы упростить работу, добавим в структуру элемента дерева (см. рис. 1.12) дополнительное поле next:ukaz, которое будет служить для связки стека:
stek:= nil;
while not eof(f) do
begin
new(p);
read(f,p^.symbol);
if p^.symbol in ['+','-','*','/']
then begin
p^.right:= stek;
p^.left:= stek^.next;
p^.next:= stek^.next^.next;
stek:= p
end
else begin
p^.left:= nil;
p^.right:= nil;
p^.next:= stek;
stek:= p
end;
end;Обходы деревьев и графов
Прежде чем приступить к изложению алгоритмов обхода, дадим пару необходимых определений.
Обход дерева - это некоторая последовательность посещения всех его вершин.
Обход графа - это обход некоторого его каркаса.
В этом разделе будут представлены только алгоритмы обхода бинарных деревьев. Большинство из них может быть с легкостью изменено для случая произвольного корневого дерева, каковым является и каркас произвольного графа.
Напомним, что структуру бинарного дерева мы описываем следующим образом:
type ukazatel = ^tree;
tree = record mark: integer;
left: ukazatel;
right: ukazatel;
end;Итак, приступим теперь к изучению различных вариантов обхода деревьев и графов.
Прямой обход
Другие названия
Префиксный обход: результатом прямого обхода3Точнее, результатом печати значений, содержащихся в вершинах ДСА. дерева синтаксического анализа арифметического выражения будет префиксный вариант записи этого выражения.
Обход в глубину "сверху вниз": название имеет смысл лишь в случае стандартного расположения дерева корнем кверху.
Алгоритм PreOrder
- Начать с корня дерева.
- Пометить4Вместо простой пометки вершины здесь можно производить выполнение любой осмысленной функции. текущую вершину.
- Совершить прямой обход левого поддерева.
- Совершить прямой обход правого поддерева.
Замечание: Этот алгоритм может быть естественным образом распространен и на случай произвольного корневого дерева.
Реализация
procedure preorder(p:ukaz; k:integer);
begin p^.mark:= k;
if p^.left<>nil then preorder(p^.left,k+1);
if p^.right<>nil then preorder(p^.right,k+1);
end;
begin
...
preorder(root,1); {Вызов из тела программы}
...
end.
