Mega Code Archive

 
Categories / Delphi / Examples
 

A Simple Tree Class

Title: A Simple Tree Class Question: How do I create a Tree Class Answer: A Simple Tree Class Here is a simple tree class To add nodes first create a TTreeNode object and then use the AddNode function of the TTree class -Code- unit TreeClass; interface uses classes,sysutils; type TTreeNode=class; TErrorObject = class(Exception); TTree=class private fremoveall:boolean; findex:integer; fRootnode:Ttreenode; fnodes:Tlist; function GetNodeFromIndex(index:integer):TTreeNode; function GetCount:integer; public constructor Create; destructor destroy;override; function AddNode(parentnode:TTreeNode):TTreeNode; procedure RemoveNode(anode:TTreeNode); procedure Clear; property Count:integer read GetCount; property RootNode:TTreenode read frootnode; property Item[index:integer]:TTreenode read GetnodeFromIndex; end; TTreenode=class private ptree:TTree; findex:integer; frelindex:integer; flevel:integer; fdata:pointer; fchildren:Tlist; fparent:TTreenode; function GetNode(index:integer):TTreeNode; function GetCount:integer; function GetNextSibling:TTreenode; function GetFirstSibling:TTreeNode; public constructor create(atree:TTree); destructor destroy;override; procedure Clear; property Tree:Ttree read ptree; property AbsoluteIndex:integer read findex; property RelativeIndex:integer read frelindex; property Level:integer read flevel; property Count:integer read GetCount; property Data:pointer read fdata write fdata; property Children[Index:integer]:TTreenode read GetNode; property NextSibling:TTreeNode read GetNextSibling; property FirstSibling:TTreeNode read GetFirstSibling; property Parent:TTreenode read fparent; end; procedure RaiseError(const msg:string); implementation function TTree.GetCount:integer; begin result:=fnodes.count; end; function TTree.GetNodeFromIndex(index:integer):TTreeNode; begin result:=nil; if (index=0) and (index result:=TTreeNode(fnodes[index]) else RaiseError('Range Out of Bounds'); end; procedure TTree.clear; var i:integer; tmp:TTreeNode; begin fremoveall:=true; findex:=1; for i:= 1 to fnodes.count-1 do begin tmp:=TTreeNode(fnodes[i]); freeandnil(tmp); end; fnodes.clear; frootnode.fchildren.clear; fnodes.add(frootnode); fremoveall:=false; end; constructor TTreenode.create(atree:TTree); begin ptree:=atree; findex:=ptree.findex; inc(ptree.findex); fchildren:=Tlist.create; fdata:=nil; fparent:=atree.fRootnode; end; destructor TTreenode.destroy; var i:integer; tmp:TTreeNode; begin if ptree.fremoveall=false then begin ptree.fnodes.remove(self); for i:=0 to fchildren.count-1 do begin tmp:=TTreeNode(fchildren[i]); freeandnil(tmp); end; freeandnil(fchildren); end; ptree:=nil; fparent:=nil; fdata:=nil; inherited; end; function TTreenode.GetCount:integer; begin result:=fchildren.Count; end; function TTreenode.GetNode(index:integer):TTreeNode; begin result:=nil; if (index =0) and (index result:=fchildren[index] else RaiseError('Range Out of Bounds'); end; function TTreenode.GetNextSibling:TTreenode; var i,tmp1:integer; begin result:=nil; tmp1:=-1; if fparentnil then begin for i:=0 to fparent.count-1 do if fparent.children[i]=self then begin tmp1:=i; break; end; if tmp1-1 then if tmp1 result:=fparent.fchildren[tmp1]; end; end; function TTreenode.GetFirstSibling:TTreeNode; begin if fparentnil then result:=fparent.fchildren[0] else result:=self; end; procedure TTreenode.Clear; var i:integer; tmp:TTreeNode; begin for i:=0 to fchildren.count-1 do begin tmp:=TTreeNode(fchildren[i]); freeandnil(tmp); end; fchildren.clear; frelindex:=1; end; constructor TTree.Create; begin findex:=0; fremoveall:=false; fRootnode:=TTreenode.create(self); frootnode.fparent:=nil; frootnode.flevel:=0; fnodes:=Tlist.create; fnodes.add(frootnode); end; destructor TTree.destroy; begin clear; fremoveall:=true; freeandnil(frootnode); freeandnil(fnodes); inherited; end; function TTree.AddNode(parentnode:TTreeNode):TTreeNode; begin if parentnode=nil then raiseerror('Invalid Parent Node'); result:=TTreenode.create(self); result.ptree:=self; result.fparent:=parentnode; result.fdata:=nil; parentnode.fchildren.add(result); result.frelindex:=parentnode.fchildren.indexof(result); result.flevel:=parentnode.flevel+1; fnodes.Add(result); end; procedure TTree.RemoveNode(anode:TTreeNode); var i:integer; begin if anode=frootnode then RaiseError('Cannot remove root node'); anode.fparent.fchildren.Remove(anode); fnodes.Remove(anode); for i:=0 to anode.fchildren.Count-1 do begin anode.children[i].fparent:=anode.fparent; anode.fparent.fchildren.Add(anode.fchildren[i]); anode.children[i].frelindex:=anode.fparent.fchildren.indexof(anode.fchildren[i]); anode.children[i].flevel:=anode.fparent.flevel+1; end; freeandnil(anode); end; procedure RaiseError(const msg:string); begin raise TerrorObject.Create(msg); end; end.