这是我在网上找到的最快的算法
function TafDir.BuildTree(DataSet: TADODataSet; TV: TTreeView; SelfField,
SelfName, ParentField: String; ClassID: Integer): boolean;
{ 以下子函数为在表中查找第一个PNode=AIndex的记录}
function FindKey(AIndex: integer; FFirst:boolean): boolean;
begin
Result:=DataSet.Locate(ParentField,AIndex,[loCaseInsensitive]);
end;
{ 以下函数在FindKey的基础上找出下一个符合的记录}
function FindNext(AIndex: integer): boolean;
begin
DataSet.Next;
if DataSet.Eof then
Result:=false
else
Result:=DataSet.FieldValues[ParentField]=AIndex;
if not Result then DataSet.Prior;
end;
{ 以下函数据构造当前结点的一级子树 }
function GetChildNode(index: integer; ANode: TTreeNode):integer;
var
MyNode
Node;
Node:TTreeNode;
begin
if FindKey(index,true) then
begin
new(MyNode);
with DataSet do
begin
MyNode^.ID :=FieldValues[SelfField];
MyNode^.bHasDoc := NOT FieldByName('FileName').IsNull;
MyNode^.FBM :=GetBookmark;
end;
Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
Node.Data:=MyNode;
//显示进度条
prg.Progress := prg.Progress + 1;
Result:=1;
while FindNext(index) do
begin
new(MyNode);
with DataSet do
begin
MyNode^.pID := FieldValues[ParentField];
MyNode^.ID :=FieldValues[SelfField];
MyNode^.bHasDoc := NOT FieldByName('FileName').IsNull;
MyNode^.FBM :=GetBookmark;
end;
Node:=TV.Items.AddChild(ANode,DataSet.FieldValues[SelfName]);
Node.Data:=MyNode;
//显示进度条
prg.Progress := prg.Progress + 1;
Result:=Result+1;
end;
end
else
Result:=0;
end;
{ 以下函数据以ANode 为结当,构造一棵属于自己的子树}
procedure BuildMe(AIndex: integer; ANode: TTreeNode);
var
NodeNum:integer;
Node:TTreeNode;
i:integer;
begin
NodeNum:=GetChildNode(AIndex,ANode);
if NodeNum>0 then
begin
if ANode=nil then Node:=TV.Items.GetFirstNode
else
Node:=ANode.getFirstChild;
for i:=1 to NodeNum do
begin
BuildMe(PNode(Node.Data)^.ID,Node);
Node:=ANode.GetNextChild(Node);
end;
end;
end;
// 组合部份
var
time:TDateTime;
oldcur:TCursor;
begin
time := Now;
oldcur:=Screen.Cursor;
Screen.Cursor :=crHourGlass;
tvwClass.Enabled := False;
TV.Items.BeginUpdate;
prg := TGauge.Create(nil);
Try
prg.Parent:=sb;
prg.SetBounds(sb.Panels[0].Width+3,3,Self.Width-sb.Panels[0].Width-8,sb.Height-4);
prg.BackColor:=clBtnFace;
prg.ForeColor:=clInactiveCaption;
prg.BorderStyle:=bsNone;
with DataSet do
Begin
Close;
Parameters.ParamByName('ClassID').Value := ClassID;
Open;
prg.Visible := True;
prg.MaxValue := RecordCount;
prg.Progress := 1;
end;
sb.Panels[0].Text := '正在清除目录结构...';
sb.Refresh;
FreeTvwData(TV);
TV.Items.Clear;
sb.Panels[0].Text := '正在载入目录结构...';
sb.Refresh;
BuildMe(0,nil);
Result:=true;
Finally
Screen.Cursor := oldCur;
TV.Items.EndUpdate;
tvwClass.Enabled := True;
prg.Free;
end;
sb.Panels[0].Text := '载入目录耗时:'+FormatDateTime('nn:ss:zz',now-time);
end;