Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
2011_12 Комп.Науки_2сем.doc
Скачиваний:
4
Добавлен:
13.09.2019
Размер:
476.67 Кб
Скачать

21.4.3.Способы обхода дерева

Обходом дерева называется последовательное обращение ко всем узлам. Существует четыре принципа упорядоченного обхода дерева, которые вытекают из его структуры. Как и саму древовидную структуру, их удобно выразить с помощью рекурсии.

Для иллюстрации обхода возьмем дерево, построенное для арифметического выражения a*b + c/d с двухместными операциями. Замечание: для произвольного дерева обходы будут выполняться точно так же, но будут иметь другую интерпретацию.

В этом дереве каждая операция изображается узлом с операндами в качестве поддеревьев.

Обозначим через Root корень дерева, а через L и R – левое и правое поддеревья.

Различные принципы обхода дают различные формы записи выражения.

  1. Прямой обход, или обход сверху вниз (Root, L, R – посетить корень, затем левое и правое поддерево) дает префиксную форму записи выражения, когда знак операции находится перед операндами: +*ab/cd

  2. Обратный обход, или обход снизу вверх (L, R, Root – посетить левое и правое поддерево, затем корень) дает постфиксную форму записи выражения, когда знак операции находится после операндов: ab*cd/+ Постфиксная нотация – форма записи математических выражений, в которой операнды расположены перед операторами.

  3. Синтаксический обход, или обход слева направо (L, Root, R – посетить левое поддерево, затем корень и правое поддерево) дает привычную инфиксную форму записи выражения, когда знак операции находится между операндами, к которым эта операция применяется: a*b + c/d

  4. Обход справа налево (R, Root, L – посетить правое поддерево, затем корень и левое поддерево) используется для печати дерева.

Опишем обходы в виде рекурсивных процедур с параметром t, означающим ссылку на узел дерева, в частности, корень дерева. Ссылка t передается по значению, так как никаких изменений структуры дерева не происходит. Процедуры обхода вызывают некоторую процедуру OP для выполнения действий в каждом узле, например, печать узла, проверка узла на максимум и т.п.

Способы обхода дерева отличаются:

  • порядком просмотра поддеревьев (левое, затем правое или правое, затем левое);

  • выполнением операции над текущим узлом (на рекурсивном спуске или на рекурсивном возврате).

procedure Prefix (t: ref);

{Обход сверху вниз Root, L, R}

begin {дает префиксную запись выражения}

if (t<>nil)

then begin

OP(t); {Выполняется в текущем узле на рекурсивном

спуске}

Prefix(t^.Left); {Переход в левое поддерево}

Prefix(t^.Right) {Переход в правое поддерево}

end

end;

procedure Postfix(t: ref);

{Обход снизу вверх L, R Root}

begin {дает постфиксную запись выражения}

if (t<>nil)

then begin

Postfix(t^.Left); {Переход в левое поддерево}

Postfix(t^.Right);{Переход в правое поддерево}

OP(t) {Выполняется в текущем узле на рекурсивном

возврате}

end

end;

procedure Infix(t: ref);

{Обход слева направо L, Root< R}

begin {дает инфиксную, обычную запись}

if (t<>nil)

then begin

Infix(t^.Left);{Переход в левое поддерево}

OP(t); {Выполняется в текущем узле

на рекурсивном возврате из левого поддерева

перед рекурсивным спуском в правое поддерево}

Infix(t^.Right) {Переход в правое поддерево}

end

end;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]