1. Заголовок темы должен быть информативным. В противном случае тема удаляется ... 2. Все тексты программ должны помещаться в теги [code=pas] ... [/code]. 3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора). 5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM! 6. Одна тема - один вопрос (задача) 7.Проверяйте программы перед тем, как разместить их на форуме!!! 8.Спрашивайте и отвечайте четко и по существу!!!
Программа сравнения двух бинарных деревьев, Не могу разобраться, как работает данная программа
Помогите, пожалуйста, разобраться в следующей программе.
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}
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 (я так понял, что выход осуществляется когда тор станет меньше нуля, но по тексту он только возрастает, так каким образом осуществляется выход из цикла?). Буду БЛАГОДАРЕН Всем, кто может помочь разобраться с этой ЗАДАЧЕЙ.