Помощь - Поиск - Пользователи - Календарь
Полная версия: Прямой обход дерева
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Vandrouny
Доброго времени суток!
Пишу вот лабу про деревья.
Суть её такова: построить дерево и реализовать прямой его обход (там ещё обратный и симметричный, но пока хоть бы прямой). Но не простой обход, а полный: показать, какие вершины последовательно анализируются.
Т.е., если в дерево вогнать последовательно 8,6,4,1,2,3,15,11,13,9,5 - он вывел
8-6-4-1-0-1-2-0-2-3-0-3-0-3-2-1-4-5-0-5... (0 - значит, пустой лист найден)
Суть проблемы: когда надо возвращаться, моя программа не отображает этого. Т.е, при этом дереве она пропускает символы:
8-6-4-1-0-1-2-0-2-3-0-3-0-4-5-0-5... (нету этого возврата 3-2-1)
Помогите, пожалуйста!


program tree;
uses crt;
Type tekst = integer;
adrzv = ^zveno;
zveno = record
kl:integer;
inf:tekst;
lev,prav:adrzv;
end;

var
t:adrzv;
n,c,f,i,y,otvet:integer;
mn: set of 1..100;
Procedure add(var S: adrzv; k: integer); {добавление элементов}
Begin
If s = nil
 then
   Begin
   New(s);
   s^.kl:=k;
   s^.lev:=nil;
   s^.prav:=nil;
   End
 else
If k < s^.kl then add(s^.lev, k);
If k > s^.kl then add(s^.prav, k);
End;



Procedure show(var s:adrzv; h: integer);  {вывод дерева}
Var i: integer;
Begin
If s <> nil then
   Begin
   show(s^.prav, h + 4);
   For i:=1 to h do write(' ');
   Writeln(s^.kl);
   show(s^.lev, h + 4);
   End
End;

Procedure direct(var s:adrzv); {процедура обхода}
Var i: integer;
Begin
   if s= nil then write('0 ')
   else
   begin
   if s^.kl in mn then write(s^.kl,' ')
   else begin mn:=mn+[s^.kl]; write(s^.kl,'+ '); end;
   direct(s^.lev);
   if s^.kl in mn then write(s^.kl,' ')
   else begin mn:=mn+[s^.kl]; write(s^.kl,'+ '); end;
   direct(s^.prav);
   end;
End;

begin clrscr;
writeln('random or not?(1/2)');
read(otvet);
case otvet of
1: begin
   randomize;
   for i:=1 to 10 do add(t,random(20));
   end;

2: begin
   writeln('enter number of elements');
   readln(n);
   writeln('enter elements');
   for i:=1 to n do
     begin
     read(c);
     add(t,c);
     end;
   end;
end;
show(t,c);
direct(t);
readkey;
end.
volvo
Цитата
когда надо возвращаться, моя программа не отображает этого
Ты ж не просишь ,вот и не отображает... Я вот так попросил:
procedure direct(var s: adrzv);
begin
  if s = nil then write(0, ' ')
  else begin
    if s^.kl in mn then write(s^.kl,' ')
    else begin mn:=mn+[s^.kl]; write(s^.kl,'+ '); end;
    direct(s^.lev);

    write(s^.kl, ' ');

    direct(s^.prav);
    if s^.kl in mn then write(s^.kl,' ')
    else begin mn:=mn+[s^.kl]; write(s^.kl,'+ '); end;
  end;
end;
Vandrouny
Спасибо, помогло!
Двигаюсь дальше, возникла ещё одна проблема: в обратном обходе непонятно, как правильно реализовать пометку плюсом элемента, который обрабатывается (т.е. если он просто проходится - без плюса, а если обрабатывается - с плюсом).

Procedure back(var s:adrzv);
Var i: integer;
Begin
   if s= nil then write(0,' ')
   else
   begin
   write(s^.kl,' ');
   direct(s^.lev);
   write(s^.kl,' ');
   direct(s^.prav);
   if s^.kl in mn then write(s^.kl,' ')
   else begin mn:=mn+[s^.kl]; write(s^.kl,'+ '); end;
   end;
End;




Добавлено через 15 мин.
Ой, всё отменяется, я дурень несусветный)))
В процедуре back использую рекурсивно процедуру direct)
Vandrouny
А вот на последнем пункте задания совсем что-то заступорился...
Надо сделать симметричную правую прошивку дерева.
Как сделать - не представляю...
Помогите, пожалуйста...
volvo
В присоединенном документе приведен псевдокод прошивки дерева...
Vandrouny
Цитата(volvo @ 18.05.2009 21:11) *

В присоединенном документе приведен псевдокод прошивки дерева...

что-то я ничего не втыкаю...sad.gif
нет ли ещё какого-нибудь примера?
и желательно на пальцах \ по-русски?
volvo
По-русски... Не встречал. Разве что "Кнут, Дональд: Искусство программирования. Том 1 - Основные алгоритмы." открываешь на стр. 353 (раздел 2.3.1) и смотришь, там есть информация по прошитым деревьям.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.