IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения.
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

 
 Ответить  Открыть новую тему 
> Программа сравнения двух бинарных деревьев, Не могу разобраться, как работает данная программа
сообщение
Сообщение #1





Группа: Пользователи
Сообщений: 6
Пол: Мужской
Реальное имя: MAX

Репутация: -  0  +


Помогите, пожалуйста, разобраться в следующей программе.

program Laba2;
{Программа сравнения двух бинарных деревьев.
ВНИМАНИЕ: входные данные считаются заведомо корректными,
никакая проверка ошибок не предусмотрена!}

const
TAB = chr(9); {символ табуляции}

type
Element = Integer;
Tree = ^Node; {дерево}
Node = record {вершина дерева}
Data: Element; {данные}
Left: Tree; {левый сын}
Right: Tree; {правый сын}
end;

var
inFile1, inFile2: Text; {файлы двух деревьев}
inTree1, inTree2: Tree; {сцепленные представления двух деревьев}

procedure ReadTree(var F: Text; var T: Tree);
{Читает дерево, представленное иерархическим текстом, из файла F
и строит сцепленное представление дерева T}

var
level: Integer;
currLine: String;
currNumber: String;
dataStr: String;
currPos: Integer;
code: Integer;

function GetWord: String;
{Выделяет из CurrLine очередную последовательность символов,
отличных от пробела и табуляции}

var
result: String;

begin
while (currPos <= Length(currLine)) and ((currLine[currPos] = ' ')
or (currLine[currPos] = TAB)) do
currPos := currPos + 1;
result := '';
while (currPos <= Length(currLine)) and (currLine[currPos] <> ' ')
and (currLine[currPos] <> TAB) do begin
result := result + currLine[currPos];
currPos := currPos + 1;
end;
GetWord := result;
end; {GetWord}

procedure RecurseRT(var T: Tree; level: Integer);
{Читает непустое поддерево T из файла.
Параметр level содержит длину номера корневой вершины поддерева.
В момент вызова этот номер уже считан из текущей введенной строки.
В момент возврата считан номер вершины, не принадлежащей введенному
поддереву}

begin
T := New(Tree);
T^.Left := nil;
T^.Right := nil;
dataStr := GetWord; {данные корневой вершины}
Val(dataStr, T^.Data, Code);
Readln(F, currLine);
currPos := 1;
currNumber := GetWord;
while Length(currNumber) > level do begin {это сыновья}
if currNumber[Length(currNumber)] = '0' then
RecurseRT(T^.Left, level + 1)
else
RecurseRT(T^.Right, level + 1);
end;
end; {RecurseRT}

begin {ReadTree}
if EOF(F) then {пустое дерево}
T := nil
else begin
Readln(F, currLine);
currPos := 1;
currNumber := GetWord;
RecurseRT(T, 1);
end;
end; {ReadTree}

procedure PrintTree(Header: String; var T: Tree);
{Выдает на стандартный вывод текстовое представление дерева T,
предваряя его заголовком Header}

procedure RecursePT(T: Tree; number: String);
{Выдает на стандартный вывод текстовое представление поддерева T.
Параметр number задает номер корневой вершины}

var
i: Integer;

begin {RecursePT}
if T = nil then
Exit;
{Сначала печать корня}
for i := 1 to Length(number) do {Отступ}
Write(' ');
Write(number + ' ');
Writeln(T^.Data);
{Теперь сыновья}
RecursePT(T^.Left, number + '0');
RecursePT(T^.Right, number + '1');
end; {RecursePT}

begin {PrintTree}
Writeln;
Writeln(Header);
RecursePT(T, '0');
end; {PrintTree}

function TreeEquRec(T1, T2: Tree): Boolean;
{Проверяет равенство двух деревьев T1 и T2.
Рекурсивный вариант}

begin
if T1 = nil then
if T2 = nil then
TreeEquRec := true
else
TreeEquRec := false
else
if T2 = nil then
TreeEquRec := false
else
if T1^.Data <> T2^.Data then
TreeEquRec := false
else
TreeEquRec := TreeEquRec(T1^.Left, T2^.Left)
and TreeEquRec(T1^.Right, T2^.Right);
end; {TreeEquRec}

function TreeEquNonRec(T1, T2: Tree): Boolean;
{Проверяет равенство двух деревьев T1 и T2.
Нерекурсивный вариант}

var
Stack: array[1..100, 1..2] of Tree; {Стек для двух деревьев}
Top: Integer; {Указатель вершины стека}
begin
Top := 1;
Stack[Top, 1] := T1;
Stack[Top, 2] := T2;
while Top > 0 do begin {пока в стеке есть нерассмотренные поддеревья}
T1 := Stack[Top, 1];
T2 := Stack[Top, 2];
Top := Top - 1;
if T1 = nil then
if T2 = nil then begin
{В отличие от рекурсивного варианта, здесь еще рано принимать
решение, потому что Exit будет означать завершение всей работы,
без рассмотрения оставшихся поддеревьев!}
{TreeEquNonRec := true;
Exit;}
end
else begin
TreeEquNonRec := false;
{Если хоть одно различие есть, то деревья различны}
Exit;
end
else begin
if T2 = nil then begin
TreeEquNonRec := false;
Exit;
end
else begin
if T1^.Data <> T2^.Data then begin
TreeEquNonRec := false;
Exit;
end
else begin
{Раз не удалось найти различий в корневой вершине,
продолжим на поддеревьях}
Stack[Top+1, 1] := T1^.Left;
Stack[Top+1, 2] := T2^.Left;
Stack[Top+2, 1] := T1^.Right;
Stack[Top+2, 2] := T2^.Right;
Top := Top+2;
end;
end;
end;
end;
{Поддеревья кончились.
Поскольку различий найти не удалось, деревья равны}
TreeEquNonRec := true;
end; {TreeEquNonRec}

begin {Laba2}
Assign(inFile1, 'Tree1.txt');
Reset(inFile1);
ReadTree(inFile1, inTree1);
PrintTree('Первое дерево:', inTree1);
Assign(inFile2, 'Tree2.txt');
Reset(inFile2);
ReadTree(inFile2, inTree2);
PrintTree('Второе дерево:', inTree2);
Writeln;
if TreeEquRec(inTree1, inTree2) then
Writeln(' Рекурсивное решение: деревья равны')
else
Writeln(' Рекурсивное решение: деревья различны');
if TreeEquNonRec(inTree1, inTree2) then
Writeln('Нерекурсивное решение: деревья равны')
else
Writeln('Нерекурсивное решение: деревья различны');
end.



Сам никак не могу понять какую структуру должны иметь файлы tree1.txt и tree2.txt. Как работает процедура ReadTree тоже не получается разобраться вот уже 3 неделю. Также не разобрался с процедурой TreeEquNonRec в части выхода из цикла при Top>0 (я так понял, что выход осуществляется когда тор станет меньше нуля, но по тексту он только возрастает, так каким образом осуществляется выход из цикла?).
Буду БЛАГОДАРЕН Всем, кто может помочь разобраться с этой ЗАДАЧЕЙ.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2





Группа: Пользователи
Сообщений: 6
Пол: Мужской
Реальное имя: MAX

Репутация: -  0  +


Тема закрыта
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 11.05.2024 0:22
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name