Помощь - Поиск - Пользователи - Календарь
Полная версия: Бинарное дерево
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
ALma
Помогите пожалуйста. Все процедуры для огранизации дерева работают. Единственное никак не получается сохранить записи в файл и при повторном запуске их прочитать.


program lab10;
uses CRt;

type
data =record
 nomer:integer;
 F,I,O:string[15];
 Ocenki:record
   math,history,physyc:integer
   end;end;
Treeprt=^tree;
 tree=record
       inf:data;
       left,right:treeprt
       end;
derevo = file of data;

var
top: treeprt;
z:data;
Level,key, n: integer;
i, number: integer;
tab: derevo;

function AddTree (top:treeprt; newnode:data):treeprt;
begin
if top=nil then
      begin
        new(top);
        top^.inf:=newnode;
        top^.left:=nil;
        top^.right:=nil;
        end
     else
      if top^.inf.ocenki.math>newnode.ocenki.math then
                 top^.left:=addTree(top^.left,newnode)
             else
              Top^.right:=addTree(top^.right,newnode);
addTree:= top;
end;

procedure OrgTree;
begin
 Writeln('procedura organizacii dereva');
 writeln('dlay vihoda *');
 writeln('=========================================');
 top:=nil;
 while true do
 begin
 writeln('vvedite Familiu');
 readln(z.F);

 if z.F='*' then exit;
 writeln('imay');
 readln(z.I);
 writeln('ot4estvo');
 readln(z.O);
writeln('vvedite ocenki');
with z.ocenki do
readln(math,history,physyc);
Top:=addTree(top,z);
end;
end;


procedure Dobl;
begin
 Writeln('procedura dobavleniay lista');
 writeln('dlay vihoda *');
 writeln('=========================================');
 writeln('vvedite Familiu');
 readln(z.F);

 if z.F='*' then exit;
 writeln('imay');
 readln(z.I);
 writeln('ot4estvo');
 readln(z.O);
writeln('vvedite ocenki');
with z.ocenki do
readln(math,history,physyc);
top:=addTree(top,z);
end;

procedure prosmotr(top:treeprt);
begin

if Top<>nil then
   begin
    prosmotr(top^.left);
    write(tab,top^.inf);
    with Top^.inf do
writeln ('³', F:10,'     ³', I:10,'    ³    ', O:10,' ³ ',ocenki.math:4,' ³   ',ocenki.history:4,' ³  ',ocenki.physyc:4,'  ³');
prosmotr(top^.right);
end;
end;


procedure Otobr (top:treeprt; Otstup:integer);
begin
 if top<> nil then
    begin
      otstup:=otstup+3;
      otobr(top^.right, otstup);
      writeln( ' ':otstup, top^.inf.ocenki.math);
      otobr(top^.left, otstup);
      end;
      end;

procedure obhod (top:treePrt);
begin
reset(tab);
if Top<>nil then
begin
obhod (Top^.Left);
read(tab, top^.inf);

obhod (Top^.Right)
end
end;

 procedure nodeCount (top:treeprt;level:integer; var n:integer);
 begin
 if (level>=1) and (top<> nil) then
 begin
  if Level=1 then n:=n+1;
  nodeCount(top^.left, level-1, n);
  nodeCount(top^.right, level-1, n);
  end;
  end;

  begin
  assign(tab,'D:\spisok.txt');{$I-}
reset(tab);{$I+}
if IOresult <> 0 then
rewrite(tab);
readln;
repeat
ClrScr;
writeln('1 - cozdanie dereva');
writeln('2 - dobavlenie lista');
writeln('3 - pods4et koli4estva vepshin');
writeln('4 - prosmotr dereva');
writeln('5 - sohranenie ,net');
writeln('6 - pe4at,net');

writeln('7 - vihod');
writeln('______________________');
writeln( 'vvedite punkt menu');
readln(key);
case key of
1:orgtree;
2:dobl;
3:begin
     writeln('vvedite # urovnay');
     read(level);
     N:=0;
     nodeCount(top,level,n);
     writeln;
     writeln('na urovne  ', level,'  ','nahoditsay  ',n,' vershin');
     writeln('najmite enter');
     readln;
     end;


4:begin
writeln ('ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ¿');
writeln ('³last_name      ', '³  ', 'first_name  ','³ ', 'ot4estvo      ³ ', 'math ³ ','history³', 'physyc  ³');
writeln ('ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄ´');
     prosmotr(top);
     writeln('======================================================');
     writeln;
     otobr(top,1);
     writeln('najmite enter');
     readln;
     end;
5:;
6:obhod(top);

end
until key=7;
end.


volvo
Если заполнение дерева и его просмотр действительно работают правильно, то добавь вот это:

procedure savetree(fn: string; top: treeprt);

var
  f: file of data;

  procedure print(t: treeprt);
  begin
    if t<>nil then begin
      print(t^.left);
      write(f, t^.inf);
      print(t^.right);
    end;
  end;

begin
  assign(f, fn);
  rewrite(f);
  print(top);
  close(f);
end;

procedure loadtree(fn: string; var top: treeprt);
var
  f: file of data;
  R: data;
begin
  assign(f, fn);
  reset(f);
  top := nil;
  while not eof(f) do begin
    read(f, R);
    top := addtree(top, R);
  end;
  close(f);
end;
, и вызывай там, где надо сохранить дерево в файл savetree(имя_файла, корень_дерева), а там, где надо восстановить - loadtree(имя_файла, будущий_корень_дерева)...
ALma
Исправила, как подсказали, но все равно не работает


program lab10;
uses CRt;

type
data =record
 nomer:integer;
 F,I,O:string[15];
 Ocenki:record
   math,history,physyc:integer
   end;end;
Treeprt=^tree;
 tree=record
       inf:data;
       left,right:treeprt
       end;
derevo = file of data;

var
top: treeprt;
z:data;
Level,key, n: integer;
i, number: integer;
tab: derevo;

function AddTree (top:treeprt; newnode:data):treeprt;
begin
if top=nil then
      begin
        new(top);
        top^.inf:=newnode;
        top^.left:=nil;
        top^.right:=nil;
        end
     else
      if top^.inf.ocenki.math>newnode.ocenki.math then
                 top^.left:=addTree(top^.left,newnode)
             else
              Top^.right:=addTree(top^.right,newnode);
addTree:= top;
end;

procedure savetree(top:treeprt; var tab: derevo);
var
  f: derevo;

  procedure print(top: treeprt);
  begin
    if top<>nil then begin
      print(top^.left);
      write(f, top^.inf);
      print(top^.right);
    end;
  end;
begin
  assign(tab, 'D:\spisok.txt' );
  assign(f,'D:\Lab10');
  rewrite(f);
  print(top);
  close(f);
end;

procedure loadtree(var tab: derevo; top: treeprt);
var
  f: derevo;
  R: data;
begin
  assign(tab, 'D:\spisok.txt' );
  assign(f,'D:\Lab10');
  reset(f);
  top := nil;
  while not eof(f) do begin
    read(f, R);
    top := addtree(top, R);
  end;
  close(f);
end;



procedure OrgTree;
begin
 Writeln('procedura organizacii dereva');
 writeln('dlay vihoda *');
 writeln('=========================================');
 top:=nil;
 while true do
 begin
 writeln('vvedite Familiu');
 readln(z.F);

 if z.F='*' then exit;
 writeln('imay');
 readln(z.I);
 writeln('ot4estvo');
 readln(z.O);
writeln('vvedite ocenki');
with z.ocenki do
readln(math,history,physyc);
Top:=addTree(top,z);
end;
end;


procedure Dobl;
begin
 Writeln('procedura dobavleniay lista');
 writeln('dlay vihoda *');
 writeln('=========================================');
 writeln('vvedite Familiu');
 readln(z.F);

 if z.F='*' then exit;
 writeln('imay');
 readln(z.I);
 writeln('ot4estvo');
 readln(z.O);
writeln('vvedite ocenki');
with z.ocenki do
readln(math,history,physyc);
top:=addTree(top,z);
end;

procedure prosmotr(top:treeprt);
begin

if Top<>nil then
   begin
    prosmotr(top^.left);
    with Top^.inf do
writeln ('³', F:10,'     ³', I:10,'    ³    ', O:10,' ³ ',ocenki.math:4,' ³   ',ocenki.history:4,' ³  ',ocenki.physyc:4,'  ³');
prosmotr(top^.right);
end;
end;


procedure Otobr (top:treeprt; Otstup:integer);
begin
 if top<> nil then
    begin
      otstup:=otstup+3;
      otobr(top^.right, otstup);
      writeln( ' ':otstup, top^.inf.ocenki.math);
      otobr(top^.left, otstup);
      end;
      end;

 procedure nodeCount (top:treeprt;level:integer; var n:integer);
 begin
 if (level>=1) and (top<> nil) then
 begin
  if Level=1 then n:=n+1;
  nodeCount(top^.left, level-1, n);
  nodeCount(top^.right, level-1, n);
  end;
  end;

  begin

repeat
ClrScr;
writeln('1 - cozdanie dereva');
writeln('2 - dobavlenie lista');
writeln('3 - pods4et koli4estva vepshin');
writeln('4 - prosmotr dereva');
writeln('5 - sohranenie ,net');
writeln('6 - pe4at,net');
writeln('7 - vihod');
writeln('______________________');
writeln( 'vvedite punkt menu');
readln(key);
case key of
1:orgtree;
2:dobl;
3:begin
     writeln('vvedite # urovnay');
     read(level);
     N:=0;
     nodeCount(top,level,n);
     writeln;
     writeln('na urovne  ', level,'  ','nahoditsay  ',n,' vershin');
     writeln('najmite enter');
     readln;
     end;


4:begin
writeln ('ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄ¿');
writeln ('³last_name      ', '³  ', 'first_name  ','³ ', 'ot4estvo      ³ ', 'math ³ ','history³', 'physyc  ³');
writeln ('ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄ´');
     prosmotr(top);
     writeln('======================================================');
     writeln;
     otobr(top,1);
     writeln('najmite enter');
     readln;
     end;
5:savetree(top,tab);
6:loadtree(tab,top);

end
until key=7;
end.
volvo
"Не работает" - это не ошибка... Я не знаю, работало ли все правильно ДО того, как внесены исправления. Какие данные вводились?

И потом, я не предлагал ТАК... Я предлагал передавать имя файла, а не саму файловую переменную описывать глобально и тягать ее туда-сюда... Не надо ПЕРЕДЕЛЫВАТЬ, а потом предъявлять претензии...
ALma
Претензий на самом деле нет никаких. Если я неправильно поняла, это только моя ошибка. Но дело не в этом.
Задание такое, программа должна создавать дерево в файле и создавать его заново при повторном запуске. Только в этом вопрос.
Я допускаю, что в моем варианте проги данные сохраняются в файле, но вот считать их оттуда не получается
volvo
Ну, смотри: сами процедуры я написал выше... Без изменений добавь их в свою программу. А вызывать - так:
begin
  repeat
    ClrScr;
    writeln('1 - cozdanie dereva');
    writeln('2 - dobavlenie lista');
    writeln('3 - pods4et koli4estva vepshin');
    writeln('4 - prosmotr dereva');
    writeln('5 - save_tree');
    writeln('6 - load_tree');
    writeln('7 - vihod');
    writeln('______________________');
    writeln( 'vvedite punkt menu');
    readln(key);
    case key of
      { Тут все пункты, от 1-го до 4-го }
      5: savetree('tree.dat', top); { <--- Можешь поменять путь к файлу }
      6: begin
        top := nil;
        loadtree('tree.dat', top); { <--- Здесь - тот же путь, что и выше... Я бы оформил его константой }
      end;
    end { case }
  until key = 7;
end.
Только что проверил... После сохранения дерева в файл и перезапуска программы дерево успешно считывается...
ALma
Да, работает, спасибо огромное. smile.gif
TheKnyazz
У меня вот затесался вопросик. Учитывая, что в данном случае мы сохраняем бинарное дерево слева направо, то оно при данном считывания вырождается в линейный список. Следовательно, как я понял, чтоб структура сохранялась процедура сохранения должна выглядеть, как идущая сверху вниз.

procedure savetree(top:treeprt; var tab: derevo);
var
  f: derevo;
  procedure print(top: treeprt);
  begin
  write(f, t^.data);
  if t^.left<>nil then  print(t^.left);
  if t^.right<>nil then  print(t^.right);
  end;
begin
  assign(tab, 'D:\spisok.txt' );
  assign(f,'D:\Lab10');
  rewrite(f);
  print(top);
  close(f);
end;

procedure loadtree(var tab: derevo; top: treeprt);
var
  f: derevo;
  R: data;
begin
  assign(tab, 'D:\spisok.txt' );
  assign(f,'D:\Lab10');
  reset(f);
  top := nil;
  while not eof(f) do begin
    read(f, R);
    top := addtree(top, R);
  end;
  close(f);
end;



Очень интересно узнать, а можно ли после записи слева направо восстановить структуру дерева?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.