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

14.Алгоритм горизонтального обхода дерева.

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

При обходе в ширину узлы посещаются уровень за уровнем(N-й уровень дерева - множество узлов с высотой N). Каждый уровень обходится слева направо. Для дерева изображенного на рисунке 1.2 обход в ширину представляет последовательность вершин:

A- BCDEFK - G

И графически (рисунок 2.4):

Заметим, что перечисление узлов происходит в порядке удаления от корня, что делает поиск в ширину удобным, например, для поиска узла дерева со значением k, наиболее близкого к корню, и т.д.

Для реализации используется структура queue - очередь с методами

enqueue - поставить в очередь

dequeue - взять из очереди

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

И часть программного кода для данного обхода будет соответственно иметь вид:

/*ОБХОД В ШИРИНУ*/

q.enqueue(root); // корень в очередь

while (! q.empty) {

der = q.dequeue();

visit der; // посетить der

if (! der.left.empty) // der.left - левое поддерево

q.enqueue(der.left);

if (! der.right.empty) // der.right - правое поддерево

q.enqueue(der.right);}

15.Алгоритм вертикального обхода дерева.

2.1. Нисходящий обход.

Как было описано ранее, нисходящий или прямой обход дерева выглядит следующим образом: корень - левое поддерево - правое поддерево.

Для дерева, изображённого на рисунке 1.2 нисходящий обход представляет собой последовательность вершин:

A-B-D-G-E-C-F-K

Наглядно это представлено на рисунке 2.1:

Программный код для прямого обхода бинарного дерева будет иметь вид:

Пример 2.1.1

/*ОБХОД В ПЯМОМ ПОРЯДКЕ (НИСХОДЯЩИЙ ОБХОД)*/

void pram_ob (derevo *&svob)

{

if (NULL==svob) return; //Если дерева нет, выходим

printf("%d\n",svob->x); //Посетили узел

pram_ob (svob->left); //Обошли левое поддерево

pram_ob (svob->rite); //Обошли правое поддерево

}

Помимо рекурсивного обхода, существует инерационный прямой обход с использованием стека. Его программный код будет иметь вид:

void pram_iter_ob(derevo *current, int l)

{

int flag=0;

while(flag==0)

{

while(current!=NULL)

{

l++;

Push(current, l);

for( int i=0; i<l; i++)

cout << "\t";

cout << current->info << endl;

current=current->left;

}

if(stack==NULL)

flag=1;

else

{

l=Pop(&current);

current=current->right;

} } }

2.2. Восходящий обход.

Восходящий обход осуществляется по схеме: левое поддерево - правое поддерево – корень. Для дерева, изображённого на рисунке 1.2 нисходящий обход представляет собой последовательность вершин:

G-E-D-B-F-K-C-A

Графически это выглядит так (рисунок 2.2):

2.3. Смешанный обход

Смешанный обход осуществляется по схеме: левое поддерево – корень – правое поддерево. Для дерева изображенного на рисунке 1.2 смешанный обход представляет последовательность вершин:

GDBEAFCK

Выглядит это следующим образом (рисунок 2.3):