數(shù)據(jù)庫表TreeView樹的快速生成
根據(jù)數(shù)據(jù)表的內(nèi)容生成TreeView樹狀結(jié)構(gòu),通常的做法就是從頂級開始,然后逐項遞歸查詢遍歷生成。這種方法在實現(xiàn)上容易做到,也很容易想到,但是效率比較低,因為數(shù)據(jù)庫的檢索(SQL語句需要解釋執(zhí)行,而且是對數(shù)據(jù)庫文件進行操作)還是比較耗時的,尤其是樹的層次較多,節(jié)點較多的情況。這里我要介紹的方法是以空間換取時間,只進行一次數(shù)據(jù)庫檢索,提取出全部數(shù)據(jù),然后一次生成TreeView樹狀結(jié)構(gòu)。通過SQL語句,讓返回的記錄按照父節(jié)點ID、節(jié)點ID進行排序,這樣保證每次當(dāng)前要添加的節(jié)點記錄的父節(jié)點都已經(jīng)添加到了TreeView樹中,剩下的工作就是如何在TreeView樹中找到父節(jié)點。這里我采用了一個排序的TStringList列表,通過排序列表采用二分查找的快速性能,就能夠很快地查找到當(dāng)前要添加節(jié)點的父節(jié)點,從而插入到TreeView樹的正確位置。
源代碼如下(假定數(shù)據(jù)表名稱為FTree,字段有ID, ParentID, Name):
procedure MakeTree(Query: TQuery; TreeView: TTreeView);
var
List: TStringList;
Node: TTreeNode;
Index: Integer;
begin
TreeView.Items.BeginUpdate;
try
TreeView.Items.Clear;
List := TStringList.Create;
try
List.Sorted := True;
while not Query.Eof do
begin
if Query.FieldByName('ParentID').AsInteger = 0 then { ParentID=0,頂層節(jié)點 }
Node := TreeView.Items.AddChild(nil, Query.FieldByName('Name').AsString)
else
begin
Index := List.IndexOf(Query.FieldByName('ParentID').AsString);
Node := TreeView.Items.AddChild(TTreeNode(List.Objects[Index]),
Query.FieldByName('Name').AsString);
end;
List.AddObject(Query.FieldByName('ID').AsString, Node);
Query.Next;
end;
finally
List.Free;
end;
finally
TreeView.Items.EndUpdate;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
T: DWORD;
begin
T := GetTickCount;
Query1.SQL.Text := 'SELECT * FROM FTree ORDER BY ParentID, ID';
Query1.Open;
MakeTree(Query1, TreeView1);
Label1.Caption := Format('MakeTree所用時間: %d ms', [GetTickCount - T]);
end;
本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請
點擊舉報。