На этом шаге мы рассмотрим нерекурсивные алгоритм изображения бинарного дерева.
Пусть бинарное дерево построено с помощью описанного на предыдущем шаге нерекурсивного алгоритма и определено указателем t.
Нам понадобятся два стека, которые мы реализуем на базе однонаправленных списков. Тип звеньев стека опишем так:
struct no
{
no *sled; // Указатель на вершину.
node *elem; // Информационное поле.
int ch; // Уровень вершины.
}
Изобразим схематично звено стека:

Рис.1. Звено стека
Опишем используемые переменные:
no *stk; // Стек "левых" ссылок.
no *stk1; // Стек "правых" ссылок.
node *u; // Указатель на структуру.
Теперь приведем и сам алгоритм:
stk = stk1 = NULL; // Первоначально оба стека пусты.
n = 0;
while (t!=NULL)
{
PushStack (&stk1,&t,&n);
// Пока не достигнут лист дерева, в стек stk помещаются
// левые ссылки тех структур, по которым перемещается
// указатель t.
if ((*t).Right!=NULL)
{ if ((*t).Left!=NULL) PushStack (&stk,&(*t).Left,&n); t = (*t).Right;}
else {
// Как только будет достигнут самый правый лист, проверяем левую
//ссылку. Если она существует, то из стека правых ссылок удаляем
//последний адрес, и на печать выводим поле ключа этой вершины.
if ((*t).Left!=NULL)
{ if (stk1!=NULL)
{ PopStack (&stk1,&u,&n);
for (i=0; i<=n; i++) cout<<" ";
cout<<(*u).Key<<endl; }
t = (*t).Left; }
if (stk==NULL) t = NULL;
else {
// Если у вершины дерева указатели на правое и
// левое поддеревья равны NULL, а стек левых
// указателей не пуст, то...
while ((*stk).elem!=(*((*stk1).elem)).Left)
{ // Удаляется адрес из стека правых ссылок
//и на печать выводится значение поля ключа
//вершины с данным адресом
PopStack (&stk1,&u,&n);
for (i=0; i<=n; i++) cout<<" ";
cout<<(*u).Key<<endl; }
// Как только выполнится условие
//((*stk).elem==(*((*stk1).elem)).Left), удаля-
//ются адреса из обоих стеков, а поле ключа
//также выводится на экран дисплея.
PopStack (&stk1,&u,&n);
for (i=0; i<=n; i++) cout<<" ";
cout<<(*u).Key<<endl;
PopStack (&stk,&t,&n); }
}
n = n + 1;
}
VyvodStack (&stk1);
Оформим алгоритм в виде функции на языке C++:
void VyvodTree (node *t) // Изображение дерева, заданного указателем t, // на экране дисплея (нерекурсивный алгоритм). { no *stk, *stk1; node *u; int i,n; stk = stk1 = NULL; n = 0; while (t!=NULL) { PushStack (&stk1,&t,&n); if ((*t).Right!=NULL) { if ((*t).Left!=NULL) PushStack (&stk,&((*t).Left),&n); t = (*t).Right; } else { if ((*t).Left!=NULL) { if (stk1!=NULL) { PopStack (&stk1,&u,&n); for (i=0; i<=n; i++) cout<<" "; cout<<(*u).Key<<endl; } t = (*t).Left; } else if (stk==NULL) t = NULL; else { while ((*stk).elem!=(*((*stk1).elem)).Left) { PopStack (&stk1,&u,&n); for (i=0; i<=n; i++) cout<<" "; cout<<(*u).Key<<endl; } PopStack (&stk1,&u,&n); for (i=0; i<=n; i++) cout<<" "; cout<< (*u).Key<endl; PopStack (&stk,&t,&n); } } n = n + 1; } VyvodStack (&stk1); }
На следующем шаге мы приведем пример построения и изображения бинарного дерева с помощью нерекурсивных алгоритмов.