unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, StdCtrls;
type
pTNode=^TNode;
TNode=class
fChild:string;
nSibling,id:string;
firstChild,nextSibling:PTnode;
Function GetFirstChild:PTNode;
Function GetNextSibling:PTNode;
end;
type
TNodeArray=array of TNode;
type
TTree=class
current,root:PTNode;
constructor Create(var arr:TNodeArray); overload;
procedure InitTree(var arr:TNodeArray;p:PTNode);
procedure GetLeaves(p:PTNode);
function FindNode(p:PTNode;s:string):boolean;
end;
type
TForm1 = class(TForm)
Button1: TButton;
Query: TADOQuery;
Memo1: TMemo;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
procedure InitArray(var arr:TNodeArray);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
function TNode.GetFirstChild:PTNode;
begin
result:=firstchild;
end;
function TNode.GetNextSibling:PTNode;
begin
result:=Nextsibling;
end;
function TTree.FindNode(p:PTNode; s:string):boolean;
begin
result:=false;
if p<>nil then
begin
if p.id=s then
begin
current:=p;
result:=true;
exit;
end;
result:=FindNode(p.firstChild,s);
if not result then
result:=FindNode(p.nextSibling,s);
end;
end;
procedure TTree.GetLeaves(p:PTNode);
begin
if p<>nil then
begin
if p.firstChild=nil then form1.Memo1.Lines.Add(p.id);
getLeaves(p.firstChild);
getLeaves(p.nextSibling);
end;
end;
procedure TForm1.InitArray(var arr:TNodeArray);
var
i:integer;
node:TNode;
begin
Query.Open;
SetLength(arr,Query.RecordCount);
for i:=0 to Query.RecordCount-1 do
begin
node:=TNode.Create;
node.id:=Query.Fields[0].AsString;
node.fChild:=Query.Fields[1].AsString;
node.nSibling:=Query.Fields[2].AsString;
arr[i]:=node;
Query.Next;
end;
Query.Close;
end;
constructor TTree.Create(var arr:TNodeArray);
var
i:integer;
begin
try
for i:=0 to length(arr)-1 do
begin
if arr[i].id='0' then root:=@arr[i]; //取根结点指针
end;
except
showmessage('error');
end;
end;
procedure TTree.InitTree(var arr:TNodeArray;p:PTNode);
var
i:integer;
begin
if p.fChild='none' then p.firstChild:=nil;
if p.nSibling='none' then p.nextSibling:=nil;
for i:=0 to Length(arr)-1 do
begin
if p.fChild=arr[i].id then
begin
p.firstChild:=@arr[i];
InitTree(arr,p.firstchild);
end;
if p.nsibling=arr[i].id then
begin
p.nextsibling:=@arr[i];
InitTree(arr,p.nextsibling);
end;
end;
end;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
tree:TTree;
arr:TNodeArray;
i:integer;
s1,s2:string;
begin
initarray(arr);
tree:=Ttree.Create(arr);
tree.InitTree(arr,tree.root);
memo1.Clear;
memo1.Lines.Add('本结点 左孩子 右兄弟');
for i:=0 to length(arr)-1 do //test
begin
if arr[i].firstChild=nil then s1:='n' else s1:=arr[i].firstchild.id; //n表示'none' ,列表应该和数据库中一致
if arr[i].nextSibling=nil then s2:='n' else s2:=arr[i].nextsibling.id;
memo1.Lines.Add(arr[i].id+' '+s1+' '+s2);
end;
tree.Free;
end;
procedure TForm1.Button2Click(Sender: TObject);
var
tree:TTree;
arr:TNodeArray;
begin
initarray(arr);
tree:=Ttree.Create(arr);
tree.InitTree(arr,tree.root);
memo1.Clear;
tree.getLeaves(tree.root);
tree.Free;
end;
procedure TForm1.Button3Click(Sender: TObject);
var
tree:TTree;
arr:TNodeArray;
begin
initarray(arr);
tree:=Ttree.Create(arr);
tree.InitTree(arr,tree.root);
memo1.Clear;
if tree.FindNode(tree.root,Trim(edit1.text)) then
memo1.Lines.Add(tree.current.id)
else memo1.Lines.Add('notfound');
tree.Free;
end;
end.