Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Lektsii_TRPO / 7_8_BinTree1_lec.doc
Скачиваний:
54
Добавлен:
12.03.2015
Размер:
532.48 Кб
Скачать

5.3. Обход бд.

Существует достаточно много алгоритмов работы с древовидными структу­рами, в которых часто встречается понятие обхода (traversing) дерева или "про­хода" по дереву. При таком методе исследования дерева каждый узел посещается только один раз, а полный обход задает линейное упорядочивание узлов, что позво­ляет упростить алгоритм, так как при этом можно использовать понятие "следую­щий" узел. т.е. узел стоящий после данного при выбранном порядке обхода.

Существует несколько принципиально разных способов обхода дерева:

Прямой (левый) обход ( TLR ): попасть в корень;

обойти левое поддерево;

обойти правое поддерево;

Обратный (симметричный) обход ( LTR ): обойти левое поддерево;

попасть в корень;

обойти правое поддерево;

Концевой (правый) обход ( LRT ): обойти левое поддерево;

обойти правое поддерево;

попасть в корень;

Обход в ширину: при обходе в ширину узлы

посещаются уровень за

уровнем(n-й уровень дерева

- множество узлов с высотой

n). Каждый уровень обходится

слева направо.

Для примера на рис.5.1. эти способы обходов дают следующую последователь­ность просмотра вершин:

а) прямой - A B D C E G F H J;

б) обратный - D B A E G C H F J;

в) концевой - D B G E H J F C A.

г) в ширину - A B C D E F G H J

Рассмотрим рекурсивную реализацию первых трех способов обхода деревьев.

Рrocedure Obhod (h:u); {способ обхода LTR}

Begin

If h<>nil Then Begin

{1} Obhod (h^. L); {обойти левое поддерево; }

{2} Write (h^. i); { попасть в корень; }

{3} Obhod (h^. R); { обойти правое поддерево;}

End;

End;

Замечания.

1. Все остальные способы обхода реализуются соответствующей перестановкой опера­торов 1, 2, 3 в процедуре Obhod.

2. Реализация обходов БД с помощью рекурсивной процедуры не вызывает затрудне­ний. В некоторых случаях из соображений эффективности применение яв­ной рекурсии оказывается нежелательным. Следующий очевидный алгоритм реали­зует наиболее популярный концевой обход LTR без рекурсии, но с использова­нием стека.

Начиная с корня продвигаемся по левым ссылкам и пройденные вершины запомина­ются в стеке. При достижении текущим указателем значения Nil в каче­стве следующей берется вершина из стека, производятся действия в данной вер­шине диктуемые конкретной решаемой задачей и следует продвижение по правой ссылке. После обхода всех вершин стек становится пустым и происходит выход.

Пример программной реализации приводится ниже.

{ h указатель на корень дерева;}

{ sр указатель стека.}

Рrocedure Obhod ( h :u );

Var р :u;

Begin

р:=h; sр:=Nil;

While ( р < > Nil) Or Not Emрty (sр) Do

If р = Nil

Then Begin р:= Рoр (sр); Writeln (р^. i); р:= р^. R; End

Else Begin Рush (sр, р); р:= р^. L; End;

End;

Для реализации обхода в ширину требуется структура типа «очередь» с методами:

РushQ - поставить в очередь;

РoрQ - взять из очереди;

EmрtyQ - возвращает TRUE, если очередь пуста, иначе - FALSE.

Рrocedure Obhod_Q( h :u );

Var t:u;

Begin

РushQ(h); { корень в очередь}

While Not EmрtyQ Do Begin

t:=РoрQ; {взять из очереди}

Write(t^.i:3) {посетить t }

If t^.L<>Nil Then РushQ(t^.L); { левое поддерево в очередь}

If t^.R<>Nil Then РushQ(t^.R); { правое поддерево в очередь}

End;

End;

Соседние файлы в папке Lektsii_TRPO