Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ответы аисд.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.94 Mб
Скачать

40.Нерекурсивный алгоритм обхода бинарного дерева.

Учитывая важность эффективной реализации обходов бинарных деревьев, рассмотрим нерекурсивные процедуры обходов. Общий нерекурсивный алгоритм для всех трех порядков обхода использует стек S для хранения упорядоченных пар (pn), где p узел бинарного дерева, а n номер операции, которую надо применить к p, когда пара (pn) будет выбрана из стека. Операции «посетить корень», «пройти левое поддерево», «пройти правое поддерево» нумеруются числами 1, 2, 3 в зависимости от порядка их выполнения в данном варианте обхода. В алгоритме эти операции будут реализованы следующим образом:

посетить корень – посетить (p);

пройти левое поддерево  if not Null (Left (p)) then S  (Left (p), 1);

пройти правое поддерево  if not Null (Right (p)) then S  (Right (p), 1).

Здесь и далее для краткости и наглядности использованы следующие обозначения операций со стеком: S  e вместо := Push (eS) и  S вместо Pop2 (eS).

Тогда общий алгоритм имеет вид:

procedure обход (bBTree);

var SStack of (BTreeoperation);

pBTreeopoperation {=1..3};

begin 

:= CreateS  (b, 1);

while not Null (Sdo 

begin (pop)  S;

if op = 1 then begin S  (p, 2); операция 1 end

else if op = 2 then begin S  (p, 3); операция 2 end 

else {op = 3} операция 

end{while}

end{обход}

В случае КЛП-обхода можно существенно упростить алгоритм, исключая лишние для этого варианта манипуляции со стеком. Здесь нет необходимости хранить в стеке номер операции. Итак, конкретизация (с упрощением) общего алгоритма для КЛП-обхода имеет вид:

procedure обход_КЛП (bBTree); {прямой}

var SStack of BTreepBTree;

begin 

S:= CreateS  b;

while not Null (Sdo 

begin 

p  S; посетить (p);

if not Null (Right (p)) then S  Right (p);

if not Null (Left (p)) then S Left (p)

end{while}

end{обход_КЛП}

В случае ЛКП-обхода также возможно некоторое упрощение  в стеке сохраняются указания лишь на операции 1 или 2:

procedure обход_ЛКП (bBTree); {обратный}

var S: Stack of (BTreeoperation);

pBTreeopoperation {=1..2};

begin S:= CreateS  (b , 1);

while not Null (Sdo 

begin (pop)  S;

if op = 1 then

begin S  (p, 2); if not Null (Left (p)) then S  (Left (p), 1)

end 

else {op=2}

begin

посетить (p); if not Null (Right (p)) then S  (Right (p), 1)

end 

end{while}

end{обход_ЛКП}

Конкретизация общего алгоритма для ЛПК-обхода (здесь нет упрощений) имеет вид:

procedure обход_ЛПК (bBTree); {концевой}

var SStack of (BTreeoperation);

pBTreeopoperation {=1..3};

begin S:= CreateS  (b, 1);

while not Null (Sdo

begin 

(pop)  S;

if op = 1 then

begin S  (p, 2); if not Null (Left (p)) then S  (Left (p), 1)

end 

else if op = 2 then 

begin 

S  (p, 3); if not Null (Right (p)) then S  (Right (p), 1)

end else {op=3 } посетить (p)

end{while}

end{обход_ЛПК}

Еще один полезный способ обхода бинарного дерева  обход в горизонтальном порядке (в ширину). При таком способе узлы бинарного дерева проходятся слева направо, уровень за уровнем от корня вниз (поколение за поколением от старших к младшим). Легко указать нерекурсивную процедуру горизонтального обхода, аналогичную процедуре КЛП-обхода (в глубину), но использующую очередь вместо стека:

procedure обход_горизонтальный (bBTree);

var Qqueue of BTree;

pBTree;

begin 

Q := Create;

Q  b;

while not Null (Qdo 

begin 

p Q;

посетить (p);

if not Null (Left (p)) then Q  Left (p);

if not Null (Right (p)) then Q  Right (p)

end{while}

end{обход_горизонтальный}

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