delphi保存并加载二叉树

时间:2012-01-11 13:14:20

标签: delphi tree binary-tree

请假设我有这个二叉树结构:

Type
    TPMyTree = ^TMyTree;
    TMyTree = Record
        ID:Integer;
        FullName:String[50];//<-------- fixed
        addrs:String[50] // <----------- fixed
        LeftT:TPMyTree;
        RightT:TPMyTree;
    end;

我如何从Stream中保存并加载它?

1 个答案:

答案 0 :(得分:1)

使用流时,最复杂的问题是处理可变长度数据。在您的情况下,这是FullNameaddrs,因为这些字段属于String类型。最简单的解决方案是使用Delphi的流读取器和编写器帮助程序类TReaderTWriter,因为它们提供了使用字符串的简单方法。另一方面,最明显的解决方案是以递归方式将树写入流中,一次一个节点。

警告,用浏览器窗口编写的代码:

// This will save one node to the stream, using the TWriter helper. Takes
// care of potential NIL's.
procedure SaveBinaryTreeToStreamWriter(RootNode: TPMyTree; W: TWriter);
begin
  if Assigned(RootNode) then
    begin
      W.WriteBoolean(True);
      W.WriteInteger(RootNode^.ID);
      W.WriteString(RootNode^.FullName);
      W.WriteString(RootNode^.addres);
      SaveBinaryTreeToStreamWriter(RootNode^.LeftT, W);
      SaveBinaryTreeToStreamWriter(RootNode^.RightT, W);
    end
  else
    W.WriteBoolean(False);
end;

// This will read one NODE from the stream, using the TReader helper.
// Uses the boolean "nil" marker saved by the writing routine to also
// return "nil" if needed.
function ReadBinaryTreeNodeFromReader(R: TReader):TPMyTree;
begin
  if R.ReadBoolean then
    begin
      Result := AllocMem(SizeOf(TMyTree));
      Result^.ID := R.ReadInteger;
      Result^.FullName := R.ReadString;
      Result^.addres := R.ReadString;
      Result^.LeftT := ReadBinaryTreeNodeFromReader(R);
      Result^.RightT := ReadBinaryTreeNodeFromReader(R);
    end
  else
    Result := nil;
end;

// This simply creates the TWriter and then starts the recursive process of
// writing the tree to stream.
procedure SaveBinaryTreeToStream(RootNode: TPMyTree; Stream: TStream);
var W:TWriter;
begin
  W := TWriter.Create(Stream, 128);
  try
    SaveBinaryTreeToStreamWriter(RootNode, W);
  finally W.Free;
  end;
end;    

// This simply creates the TReader and then starts the recursive process of
// reading the tree one node at a time:
function ReadFromStream(Stream:TStream):TPMyTree;
var R: TReader;
begin
  R := TReader.Create(Stream, 128);
  try
    Result := ReadBinaryTreeNodeFromReader(R);
  finally R.Free;
  end;    
end;