Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
13
Добавлен:
01.05.2014
Размер:
208.38 Кб
Скачать

Министерство образования Российской Федерации

Санкт–Петербургский Государственный

Электротехнический Университет

Кафедра МО ЭВМ

Дисциплина: Программирование

Отчёт по лабораторной работе №3

«Бинарные деревья»

Выполнил:

студент группы 3341, Худяков Я.Д.

Проверил:

Преподаватель, Алексеев А. Ю.

Санкт-Петербург

2004

  1. Содержательная постановка задачи.

Для заданного леса с произвольным типом элементов:

а) получить естественное представление леса бинарным деревом;

б) вывести изображение леса и бинарного дерева;

Пример решения:

Допустим, что дан лес из 2-х деревьев:

Необходимо получить представление этого леса бинарным деревом:

  1. Формальная постановка задачи.

Входные данные

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

Определение скобочного представления:

< лес > ::= пусто | < дерево > < лес >,

< дерево > ::= ( < корень > < лес > ).

Корень определим как любой символ английского алфавита.

Выходные данные

Выходными данными на экран являются сообщения об различных ошибках программы, перевёрнутая картинка исходного леса и полученного бинарного дерева и его скобочное представление(если оно было получено). Выходными данными в файле являются коментарии о чтении строк входного файла, которые имют вид:

Считываю дерево номер #...

Дерево номер # считано. Скобочная запись дерева:

##################

или

Считываю дерево номер #...

Ошибка в записи дерева номер #. Дерево не считано.

Затем картинка исходного леса, полученного бинарного дерева и его скобочное представление(если оно было получено).

Исключительные ситуации

Исключительные ситуации могут возникнуть по следующим причинам:

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

  2. Входной файл содержит лес с количеством деревьев, превышающее допустимое. В этом случае будет выдано сообщение об ошибке, ввод деревьев прекратится.

  3. Входной файл пуст. В этом случае будет выдано соответствующее сообщение.

  1. Описание алгоритма.

Исходный лес F представляется как совокупность трех частей:

1) корня первого дерева  Root (Head (F)),

2) леса поддеревьев первого дерева  Listing (Head (F)),

3) леса остальных деревьев  Tail (F).

Из этих трех частей рекурсивно порождается бинарное дерево B (F), представляющее лес F:

B (F)  if Null (F) then

else ConsBT (Root (Head (F)),

B (Listing (Head (F))),

B (Tail (F))).

Согласно этому определению корнем бинарного дерева (F) является корень первого дерева Т1 в лесу F, левым поддеревом бинарного дерева B (F) является бинарное дерево, представляющее лес поддеревьев первого дерева Т1, а правым поддеревом бинарного дерева B (F) является бинарное дерево, представляющее лес остальных (кроме первого) деревьев исходного леса F. Стоит отметить, что для реализации указанного выше определения бинарного дерева леса возникла необходимость описать некоторые тривиальные процедуры для работы с лесом деревьев.

  1. Описание программы.

Структуры данных

В данной работе БД реализованы ссылочным представлением в связанной памяти

Структура БД:

type 

BinT = ^Node; {представление бинарного дерева}

Node = record {узел: }

Info: Elem; { содержимое}

LSub: BinT; { левое поддерево}

RSub: BinT { правое поддерево}

end {Node}

Спецификация процедур и функций

Имя

Назначение

procedure Otkaz (n: Byte);

сообщения об ошибках

function CreateBT: BinT;

создание БД

function NullBT (t: BinT): Boolean;

проверка пусто ли ДБ

function RootBT (t: BinT): Elem;

значание корня БД

function LeftBT (t: BinT): BinT;

левое поддерево БД

function RightBT (t: BinT): BinT;

правое поддерево ДБ

function ConsBT (e: Elem; LS, RS: BinT): BinT;

конструктор дерева

procedure DestroyBT (var b: BinT);

удаление дерева

procedure WriteBT (D : BinT);

вывод дерева в скоб представлении на экран

procedure WriteBT1 (D : BinT);

вывод дерева в скоб представлении в файл

function Ent : BinT;

ввод дерева из файла

procedure DisplayBT1 (b: BinT; n: integer);

вывод перев изобр дерева на экран

procedure DisplayBT2 (b: BinT; n: integer);

вывод перев изобр дерева в файл

* для реализации леса использована несколько инас структура данных. См. в приложениях.

Иерархия функций

Основное тело

программы

Процедура Go

Процедуры и функции работы с бинарными деревьями

Процедура В

Процедуры DisplayBT и WriteBT

Процедуры и функции работы с деревьями (не БД) и лесом

Внешняя спецификация функций

(модуль lab3_re)

Имя

Назначение

Function TEST(S : string): boolean;

проверка правильности ввода дерева

Function Go:BinT;

функция, решающая поставленную задачу

function B(F : forest):bint;

Реализация построения БД леса

Приложение.

Листинги исходных файлов.

LABA3_re.PAS

unit laba3_re;

INTERFACE

uses crt, derevo2, derevo;

Function TEST(S : string): boolean; {проверка правильности ввода дерева}

Function Go:BinT; {функция, решающая поставленную задачу}

IMPLEMENTATION

Function TEST(S : string): boolean;

const

koren = ['a' .. 'z', 'A' .. 'Z'];

var

znach, itog, temp : boolean;

i, len : integer;

str : string;

cur : char;

procedure scan;

begin

if (i <= len) then

begin

cur := s[i];

inc(i);

end else

begin

cur := '!';

exit;

end;

end; {scan}

function TestBT : boolean;

forward;

function forest:boolean;

var znach : boolean;

begin

znach := true;

if s[i] = '(' then

begin

znach := testbt;

if znach then

begin

znach := forest;

end;

end;

forest := znach;

end;

function TestBT : boolean;

var znach : boolean;

begin

scan;

if (cur = '(') then

begin

scan;

znach := cur in koren;

if znach then

begin

znach := forest;

end;

scan;

if (cur <> ')') then

begin

znach := false;

end;

end else znach := false;

TestBT := znach;

end; {TestBT}

Begin

temp := false;

len := Length(s);

i := 1;

itog := TestBT;

itog := itog and (i <> len);

TEST := itog;

End; {TEST}

{--------END--ANALIZATOR--------------}

Function Go:BinT;

var

i,j,k,schet,num : integer;

F, LST,ls : Forest;

o,tek : Tree;

temp:BiNT;

function B(F : forest):bint;

var

ls,f1 : forest;

begin

if NullF(F) then B := nil else

begin

Listin(Head(f),ls);

Tail(Head(f),f,f1);

B := consBT(roott(Head(F)),B(ls),B(f1));

end;

end;

begin

CreateForest(F);

schet := 1;

i := 1;

if eoln(t) then

begin

writeln('Файл пуст.');

writeln(tt,'Файл пуст.');

end else

BeGin

while not eof(t) do

begin

writeln(tt,'Считываю дерево номер ',schet,'...');

readln(t,st);

y1:=length(st);

for j :=1 to y1 do

begin

if (st[j]=' ') then

begin

delete(st,j,1);

j:=1;

end;

end;

y1:=length(st);

if TEST(st) then BEGIN

tek := EnterT(st);

begin

writeln(tt,'Дерево номер ',schet,' считано. Скобочная запись дерева:');

WriteT1(tek,tt);

writeln(tt);

F[i] := tek;

inc(i);

end;

END else

begin

writeln('Ошибка в записи дерева номер ',schet,'. Дерево не считано.');

writeln(tt,'Ошибка в записи дерева номер ',schet,'. Дерево не считано.');

end;

inc(schet);

end;

dec(i);

writeln(tt,'Обработка леса...');

writeln('Обработка леса...');

{Temp := B(F);

WriteT(F[1]);

writeln; }

{DisplayBT1(Temp,1);}

{DisplayT1(F[1],1,1);}

if (i <> 0) then

begin

writeln('Исходный лес:');

writeln(tt,'Исходный лес:');

end;

for j:=1 to i do

begin

writeln('Дерево ',j,':');

writeln(tt,'Дерево ',j,':');

DisplayT1(F[j],1,1);

DisplayT2(F[j],1,1,tt);

end;

writeln;

writeln(tt);

Temp := B(F);

Go := Temp;

if (temp = nil) then

begin

writeln(tt,'Получено бинарное дерево леса пусто.');

writeln('Получено бинарное дерево леса пусто.');

end else BEGIN

writeln(tt,'Получено бинарное дерево леса:');

writeln('Получено бинарное дерево леса:');

DisplayBT1(Temp,1);

DisplayBT2(Temp,1);

writeln(tt);

writeln;

writeln('Скобочное представление бинарного дерева леса:');

writeln(tt,'Скобочное представление бинарного дерева леса:');

WriteBT(Temp);

WriteBT1(Temp);

END;

EnD;

end;{Go}

End.

DEREVO.PAS

unit Derevo;

INTERFACE

uses crt;

const

NilBT = nil;

type

BinT = ^Node;

Elem = char; {представление бинарного дерева}

{тип Elem описан в GlobalBT}

Node = record {узел:}

Info: Elem; { содержимое}

LSub: BinT; { левое поддерево}

RSub: BinT { правое поддерево}

end {Node};

var

st: string;

i,y,lenght:integer;

t,tt:text;

procedure Otkaz (n: Byte); {сообщения об ошибках}

function CreateBT: BinT; {создание БД}

function NullBT (t: BinT): Boolean; {проверка пусто ли ДБ}

function RootBT (t: BinT): Elem; {значание корня БД}

function LeftBT (t: BinT): BinT; {левое поддерево БД}

function RightBT (t: BinT): BinT; {правое поддерево ДБ}

function ConsBT (e: Elem; LS, RS: BinT): BinT; {конструктор дерева}

procedure DestroyBT (var b: BinT); {удаление дерева}

procedure WriteBT (D : BinT); {вывод дерева в скоб представлении на экран}

procedure WriteBT1 (D : BinT); {вывод дерева в скоб представлении в файл}

function Ent : BinT; {ввод дерева из файла}

procedure DisplayBT1 (b: BinT; n: integer); {вывод перев изобр дерева на экран}

procedure DisplayBT2 (b: BinT; n: integer); {вывод перев изобр дерева в файл}

{ ---------------------------------------------------------------------------------}

IMPLEMENTATION

procedure Otkaz (n: Byte);

begin

Case n of

1: Write ('ОТКАЗ: RootBT (Null_Bin_Tree)!');

2: Write ('ОТКАЗ: LeftBT (Null_Bin_Tree)!');

3: Write ('ОТКАЗ: RightBT (Null_Bin_Tree)!');

4: Write ('ОТКАЗ: исчерпана память!')

else Write ('ОТКАЗ: ?')

end;

Halt

end {Otkaz};

function CreateBT: BinT;

begin

CreateBT := nil

end {CreateBT};

function NullBT (t: BinT): Boolean;

begin

NullBT := (t = nil)

end {NullBT};

function RootBT (t: BinT): Elem;

begin

if t <> nil then RootBT := t^.Info else Otkaz(1)

end {RootBT};

function LeftBT (t: BinT): BinT;

begin

if t <> nil then LeftBT := t^.LSub else Otkaz(2)

end {LeftBT};

function RightBT (t: BinT): BinT;

begin

if t <> nil then RightBT := t^.RSub else Otkaz(3)

end {RightBT};

function ConsBT (e: Elem; LS, RS: BinT): BinT;

var b: BinT;

begin

if MaxAvail >= SizeOf (Node) then

begin

New (b);

b^.Info:= e;

b^.LSub:= LS;

b^.RSub:= RS;

ConsBT:= b

end

else

Otkaz(4)

end {ConsBT};

procedure DestroyBT(var b: BinT);

begin

if b <> nil then

begin

DestroyBt (b^.LSub);

DestroyBt (b^.RSub);

Dispose (b)

end

end {DestroyBT};

procedure WriteBT (D : BinT);

begin

write('(');

write(rootBT(D));

if (LeftBT(D) = nil) then write('0') else WriteBT(LeftBT(D));

if (RightBT(D) = nil) then write('0') else WriteBT(RightBT(D));

write(')');

end;

procedure WriteBT1 (D : BinT);

begin

write(tt,'(');

write(tt,rootBT(D));

if (LeftBT(D) = nil) then write(tt,'0') else WriteBT1(LeftBT(D));

if (RightBT(D) = nil) then write(tt,'0') else WriteBT1(RightBT(D));

write(tt,')');

end;

function Ent : BinT;

var

c : char;

begin

c := st[lenght]; inc(lenght);

if (c = '(') then

begin

c := st[lenght]; inc(lenght);

end;

if (c <> '(') and (c <> ')') then if (c = '0') then Ent := nil else

begin

Ent := ConsBT(c,Ent,Ent);

c := st[lenght]; inc(lenght);

end;

end;

procedure DisplayBT1 (b: BinT; n: integer);

{вывод построчного и повернутого изображения бинарного дерева без возврата каретки}

{n уровень узла}

var i: integer;

begin

if NullBT (b) then {Writeln}

else

begin

Write (' ', RootBT (b));

if NullBT (RightBT (b))

then Writeln {вниз}

else DisplayBT1 (RightBT (b), n+1);

if not NullBT (LeftBT (b)) then

begin

for i := 1 to n do Write (' '); {вправо}

DisplayBT1 (LeftBT (b), n+1);

end;

end;

end; {DisplayBT1}

procedure DisplayBT2 (b: BinT; n: integer);

{вывод построчного и повернутого изображения бинарного дерева без возврата каретки}

{n уровень узла}

var i: integer;

begin

if NullBT (b) then {Writeln}

else

begin

Write (tt,' ', RootBT (b));

if NullBT (RightBT (b))

then Writeln(tt) {вниз}

else DisplayBT2 (RightBT (b), n+1);

if not NullBT (LeftBT (b)) then

begin

for i := 1 to n do Write (tt,' '); {вправо}

DisplayBT2 (LeftBT (b), n+1);

end;

end;

end; {DisplayBT2}

end.

Derevo2.PAS

unit Derevo2;

INTERFACE

uses crt;

const

ForLen = 50;

NilT = nil;

type

Tree = ^tNode;

Forest = array [1..ForLen] of Tree; {лес}

Elem = char; {представление бинарного дерева}

{тип Elem описан в GlobalT}

tNode = record {узел:}

Info: Elem; { содержимое}

Sub1: Tree;

Sub2: Tree;

Sub3: Tree;

Sub4: Tree;

Sub5: Tree;

end {Node};

var

st1: string;

i1,y1,lenght1:integer;

t,tt:text;

procedure Otkaz (n: Byte); {сообщения об ошибках}

function CreateT: Tree; {создание БД}

function NullT (t: Tree): Boolean; {проверка пусто ли ДБ}

function RootT (t: Tree): Elem; {значание корня БД}

function T1 (t: Tree): Tree;

function T2 (t: Tree): Tree;

function T3 (t: Tree): Tree;

function T4 (t: Tree): Tree;

function T5 (t: Tree): Tree;

function Cons_T (e: Elem; L1,L2,L3,L4,L5: Tree): Tree; {конструктор дерева}

procedure DestroyT (var b: Tree); {удаление дерева}

procedure WriteT (D : Tree); {вывод дерева в скоб представлении на экран}

procedure WriteT1 (D : Tree;var tt:text); {вывод дерева в скоб представлении в файл}

function EnterT(s:string) : Tree; {ввод дерева из файла}

procedure DisplayT1 (b: Tree; n,l: integer); {вывод перев изобр дерева на экран}

procedure DisplayT2 (b: Tree; n,l: integer;var tt:text); {вывод перев изобр дерева на экран}

procedure CreateForest(var F : forest); {создание леса}

procedure Listin(T : Tree; var F:forest); {возвращает лес поддеревьев дерева}

procedure Tail(T : Tree; var F,F1 : forest ); {возвразает лес дерева без головы}

function Head (F : forest):Tree; {возвращает головное дерево леса}

function NullF(F:forest):boolean; {проверка пуст ли лес}

{ ---------------------------------------------------------------------------------}

IMPLEMENTATION

procedure Otkaz (n: Byte);

begin

Case n of

1: Write ('ОТКАЗ: RootT (Null_Bin_Tree)!');

2: Write ('ОТКАЗ: LeftT (Null_Bin_Tree)!');

3: Write ('ОТКАЗ: RightT (Null_Bin_Tree)!');

4: Write ('ОТКАЗ: исчерпана память!')

else Write ('ОТКАЗ: ?')

end;

Halt

end {Otkaz};

function CreateT: Tree;

begin

CreateT := nil

end {CreateT};

function NullT (t: Tree): Boolean;

begin

NullT := (t = nil)

end {NullT};

function RootT (t: Tree): Elem;

begin

if t <> nil then RootT := t^.Info else Otkaz(1)

end {RootT};

function T1 (t: Tree): Tree;

begin

if t <> nil then T1 := t^.Sub1 else Otkaz(2)

end {T1};

function T2 (t: Tree): Tree;

begin

if t <> nil then T2 := t^.Sub2 else Otkaz(2)

end {T2};

function T3 (t: Tree): Tree;

begin

if t <> nil then T3 := t^.Sub3 else Otkaz(2)

end {T3};

function T4 (t: Tree): Tree;

begin

if t <> nil then T4 := t^.Sub4 else Otkaz(2)

end {T4};

function T5 (t: Tree): Tree;

begin

if t <> nil then T5 := t^.Sub5 else Otkaz(2)

end {T5};

function Cons_T (e: Elem; L1, L2, L3, L4, L5: Tree): Tree;

var b: Tree;

begin

if MaxAvail >= SizeOf (tNode) then

begin

New (b);

b^.Info:= e;

b^.Sub1:= L1;

b^.Sub2:= L2;

b^.Sub3:= L3;

b^.Sub4:= L4;

b^.Sub5:= L5;

Cons_T:= b

end

else

Otkaz(4)

end {Cons_T};

procedure DestroyT(var b: Tree);

begin

if b <> nil then

begin

DestroyT (b^.Sub1);

DestroyT (b^.Sub2);

DestroyT (b^.Sub3);

DestroyT (b^.Sub4);

DestroyT (b^.Sub5);

Dispose (b)

end

end {DestroyT};

procedure WriteT (D : Tree);

begin

write('(');

write(rootT(D));

if (T1(D) <> nil) then WriteT(T1(D));

if (T2(D) <> nil) then WriteT(T2(D));

if (T3(D) <> nil) then WriteT(T3(D));

if (T4(D) <> nil) then WriteT(T4(D));

if (T5(D) <> nil) then WriteT(T5(D));

write(')');

end;

procedure WriteT1 (D : Tree;var tt:text);

begin

write(tt,'(');

write(tt,rootT(D));

if (T1(D) <> nil) then WriteT1(T1(D),tt);

if (T2(D) <> nil) then WriteT1(T2(D),tt);

if (T3(D) <> nil) then WriteT1(T3(D),tt);

if (T4(D) <> nil) then WriteT1(T4(D),tt);

if (T5(D) <> nil) then WriteT1(T5(D),tt);

write(tt,')');

end;

function EnterT(s:string) : Tree;

var ll:integer;

rrr:tree;

function EntT : Tree;

var

c,temp : char;

begin

c := s[ll]; inc(ll);

{ write(c); readkey; }

if (c = '(') then

begin

c := s[ll]; inc(ll);

end;

{write(c); readkey;}

if (c = ')') then

begin

EntT := nil;

ll := ll -1

end else

begin

EntT := Cons_T(c,EntT,EntT,EntT,EntT,EntT);

c := s[ll]; inc(ll);

end;

end;

begin

ll:=1;

rrr:=entt;

entert := rrr;

end;

procedure DisplayT1 (b: Tree; n,l: integer);

{вывод построчного и повернутого изображения бинарного дерева без возврата каретки}

{n уровень узла}

var i,j,k,r: integer;

begin

k:=1;

r:=1;

for j:=1 to n do k:=k+1;

k:=k+l;

if NullT (b) then {Writeln}

else

begin

for i:=1 to k do write(' ');

Write ({' ',} RootT (b)); writeln;

DisplayT1(T1(b),n+1,k);

DisplayT1(T2(b),n+1,k);

DisplayT1(T3(b),n+1,k);

DisplayT1(T4(b),n+1,k);

DisplayT1(T5(b),n+1,k);

{writeln;}

end;

end; {DisplayBT1}

procedure DisplayT2 (b: Tree; n,l: integer;var tt:text);

{вывод построчного и повернутого изображения бинарного дерева без возврата каретки}

{n уровень узла}

var i,j,k,r: integer;

begin

k:=1;

r:=1;

for j:=1 to n do k:=k+1;

k:=k+l;

if NullT (b) then {Writeln}

else

begin

for i:=1 to k do write(tt,' ');

Write (tt,RootT(b)); writeln(tt);

DisplayT2(T1(b),n+1,k,tt);

DisplayT2(T2(b),n+1,k,tt);

DisplayT2(T3(b),n+1,k,tt);

DisplayT2(T4(b),n+1,k,tt);

DisplayT2(T5(b),n+1,k,tt);

{writeln;}

end;

end; {DisplayBT1}

procedure CreateForest(var F : forest);

var t : integer;

begin

for t := 1 to ForLen do F[t] := nil;

end;

procedure Listin(T : Tree; var F:forest);

begin

CreateForest(F);

F[2] := T2(T);

F[1] := T1(T);

F[3] := T3(T);

F[4] := T4(T);

F[5] := T5(T);

end; {Listing}

procedure Tail(T : Tree; var F,F1 : forest );

var n : integer;

begin

CreateForest(F1);

for n := 1 to ForLen do

begin

if (F[n] <> T) then F1[n] := F[n];

end;

end;

function Head (F : forest):Tree;

var

n : integer;

begin

n:=1;

while ( (nullT(F[n])) and (n <= ForLen)) do inc(n);

if (n=ForLen + 1) then Head := nil else Head := F[n];

end; {Tail}

function NullF(F:forest):boolean;

var n : integer;

begin

n:=1;

while ( (nullT(F[n])) and (n <= ForLen)) do inc(n);

if (n=ForLen + 1) then NullF := true else NullF := false;

end;

end.

LABA3_M.PAS

uses crt, derevo2, DEREVO, laba3_re;

Begin

clrscr;

assign(t,'der_in.txt'); reset(t);

assign(tt,'der_out.txt'); rewrite(tt);

go;

readkey;

close(t);

close(tt);

End.

Соседние файлы в папке Бинарные деревья