数据库表TreeView树的快速生成

根据数据表的内容生成TreeView树状结构,通常的做法就是从顶级开始,然后逐项递归查询遍历生成。这种方法在实现上容易做到,也很容易想到,但是效 率比较低,因为数据库的检索(SQL语句需要解释执行,而且是对数据库文件进行操作)还是比较耗时的,尤其是树的层次较多,节点较多的情况。这里我要介绍 的方法是以空间换取时间,只进行一次数据库检索,提取出全部数据,然后一次生成TreeView树状结构。通过SQL语句,让返回的记录按照父节点ID、 节点ID进行排序,这样保证每次当前要添加的节点记录的父节点都已经添加到了TreeView树中,剩下的工作就是如何在TreeView树中找到父节 点。这里我采用了一个排序的TStringList列表,通过排序列表采用二分查找的快速性能,就能够很快地查找到当前要添加节点的父节点,从而插入到TreeView树的正确位置。

源代码如下(假定数据表名称为FTree,字段有ID, ParentID, Name):

 1 procedure MakeTree(Query: TQuery; TreeView: TTreeView);
2 var
3 List: TStringList;
4 Node: TTreeNode;
5 Index: Integer;
6 begin
7 TreeView.Items.BeginUpdate;
8 try
9 TreeView.Items.Clear;
10
11 List := TStringList.Create;
12 try
13 List.Sorted := True;
14
15 while not Query.Eof do
16 begin
17 if Query.FieldByName('ParentID').AsInteger = 0 then { ParentID=0,顶层节点 }
18 Node := TreeView.Items.AddChild(nil, Query.FieldByName('Name').AsString)
19 else
20 begin
21 Index := List.IndexOf(Query.FieldByName('ParentID').AsString);
22 Node := TreeView.Items.AddChild(TTreeNode(List.Objects[Index]),
23 Query.FieldByName('Name').AsString);
24 end;
25 List.AddObject(Query.FieldByName('ID').AsString, Node);
26 Query.Next;
27 end;
28 finally
29 List.Free;
30 end;
31 finally
32 TreeView.Items.EndUpdate;
33 end;
34 end;
35
36 procedure TForm1.Button1Click(Sender: TObject);
37 var
38 T: DWORD;
39 begin
40 T := GetTickCount;
41 Query1.SQL.Text := 'SELECT * FROM FTree ORDER BY ParentID, ID';
42 Query1.Open;
43 MakeTree(Query1, TreeView1);
44 Label1.Caption := Format('MakeTree所用时间: %d ms', [GetTickCount - T]);
45 end;

 

posted @ 2012-02-21 11:28  IT少年  阅读(1613)  评论(0编辑  收藏  举报