數(shù)據(jù)庫(kù)表TreeView樹(shù)的快速生成
根據(jù)數(shù)據(jù)表的內(nèi)容生成TreeView樹(shù)狀結(jié)構(gòu),通常的做法就是從頂級(jí)開(kāi)始,然后逐項(xiàng)遞歸查詢(xún)遍歷生成。這種方法在實(shí)現(xiàn)上容易做到,也很容易想到,但是效率比較低,因?yàn)閿?shù)據(jù)庫(kù)的檢索(SQL語(yǔ)句需要解釋執(zhí)行,而且是對(duì)數(shù)據(jù)庫(kù)文件進(jìn)行操作)還是比較耗時(shí)的,尤其是樹(shù)的層次較多,節(jié)點(diǎn)較多的情況。這里我要介紹的方法是以空間換取時(shí)間,只進(jìn)行一次數(shù)據(jù)庫(kù)檢索,提取出全部數(shù)據(jù),然后一次生成TreeView樹(shù)狀結(jié)構(gòu)。通過(guò)SQL語(yǔ)句,讓返回的記錄按照父節(jié)點(diǎn)ID、節(jié)點(diǎn)ID進(jìn)行排序,這樣保證每次當(dāng)前要添加的節(jié)點(diǎn)記錄的父節(jié)點(diǎn)都已經(jīng)添加到了TreeView樹(shù)中,剩下的工作就是如何在TreeView樹(shù)中找到父節(jié)點(diǎn)。這里我采用了一個(gè)排序的TStringList列表,通過(guò)排序列表采用二分查找的快速性能,就能夠很快地查找到當(dāng)前要添加節(jié)點(diǎn)的父節(jié)點(diǎn),從而插入到TreeView樹(shù)的正確位置。 源代碼如下(假定數(shù)據(jù)表名稱(chēng)為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é)點(diǎn) } 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所用時(shí)間: %d ms', [GetTickCount - T]); end; |
|
來(lái)自: 悟靜 > 《.net和asp.net》