我的数据库结构
Parent Child
001 002
001 003
002 004
002 010
003 030
004 100
... ...我要把这个结构加到TreeView(就是以树结构显示出来)
我现在用递归方法可以做到, 但如果数据量少的时候还没什么问题, 但如果数据量大了就惨了, 我现在已经有3000多条纪录, 做完要15秒左右, 但我的数据量还会增加的, 可能会到10000, 到时候的速度就惨不忍到了, 谁能帮我改善一下算法
我现在是这样做的
rocedure TZFMF.AddNode(Str1: string);
var
i:integer;
begin for i:=0 to ChildZFList.Count-1 do
begin
if ParentZFList.Strings[i]=str1 then
if not (TreeList.IndexOf(ChildZFList.Strings[i])<>-1) then ///// 如果List3中还不存在
begin
TreeList.AddObject(ChildZFList.Strings[i],Treeview1.Items.AddChild(TreeList.objects[TreeList.indexof(ParentZFList.Strings[i])] as TTreenode,ChildZFList.strings[i]));
AddNode(ChildZFList.Strings[i]);
end;
end;
end;
procedure TZFMF.FormShow(Sender: TObject);
begin
ParentZFList:=TStringList.Create; ///// 保存父机房
ChildZFList:=TStringList.Create; ///// 保存父机房
TreeList:=TStringList.Create; ///// 保存父机房
Treeview1.Items.Clear;
TreeList.Clear;
TreeList.AddObject('顶节点',treeview1.Items.AddChild(nil,'顶节点'));///////////把数据加到StringsList中
ParentZFList.Clear;
ChildZFList.Clear;
with MainQ do
begin
Close;
SQL.Clear;
SQL.Add('select ParentZF,ChildZF,ZFStatu From ZF Order by ParentZF,ChildZF');
Open;
end;
while not MainQ.Eof do
begin
ParentZFList.Add(MainQ.FieldByName('ParentZF').AsString); //////把父机房加入到List1中
ChildZFList.Add(MainQ.FieldByName('ChildZF').AsString); //////把子机房加入到List2中
MainQ.Next;
end;
addnode('顶节点');
end;
Parent Child
001 002
001 003
002 004
002 010
003 030
004 100
... ...我要把这个结构加到TreeView(就是以树结构显示出来)
我现在用递归方法可以做到, 但如果数据量少的时候还没什么问题, 但如果数据量大了就惨了, 我现在已经有3000多条纪录, 做完要15秒左右, 但我的数据量还会增加的, 可能会到10000, 到时候的速度就惨不忍到了, 谁能帮我改善一下算法
我现在是这样做的
rocedure TZFMF.AddNode(Str1: string);
var
i:integer;
begin for i:=0 to ChildZFList.Count-1 do
begin
if ParentZFList.Strings[i]=str1 then
if not (TreeList.IndexOf(ChildZFList.Strings[i])<>-1) then ///// 如果List3中还不存在
begin
TreeList.AddObject(ChildZFList.Strings[i],Treeview1.Items.AddChild(TreeList.objects[TreeList.indexof(ParentZFList.Strings[i])] as TTreenode,ChildZFList.strings[i]));
AddNode(ChildZFList.Strings[i]);
end;
end;
end;
procedure TZFMF.FormShow(Sender: TObject);
begin
ParentZFList:=TStringList.Create; ///// 保存父机房
ChildZFList:=TStringList.Create; ///// 保存父机房
TreeList:=TStringList.Create; ///// 保存父机房
Treeview1.Items.Clear;
TreeList.Clear;
TreeList.AddObject('顶节点',treeview1.Items.AddChild(nil,'顶节点'));///////////把数据加到StringsList中
ParentZFList.Clear;
ChildZFList.Clear;
with MainQ do
begin
Close;
SQL.Clear;
SQL.Add('select ParentZF,ChildZF,ZFStatu From ZF Order by ParentZF,ChildZF');
Open;
end;
while not MainQ.Eof do
begin
ParentZFList.Add(MainQ.FieldByName('ParentZF').AsString); //////把父机房加入到List1中
ChildZFList.Add(MainQ.FieldByName('ChildZF').AsString); //////把子机房加入到List2中
MainQ.Next;
end;
addnode('顶节点');
end;
我们能不能这么做,开始的时候只建立父一级及其儿子,孙子、重孙子县不予考虑。如果想展开那一层的儿子,那么在建立他的儿子的儿子。
这样避免了建立整棵树。主要思想就是看哪个分枝就建立哪个分支,不看得不建立。
节点还没有展开的时候那个节点的数据又看不到,所以在树节点展开的时候(OnExpanding)再载入数据会好一点,可以分流一些数据,不要一次性就把所有的数据装载到树结构
----------------------------------
一个排序的小技巧:
当你定义类或者指针的时候可以使用TList作为容器来保存结果,然后写一个回调的判断你的对象或者指针的优先级,这样可以使用TList的快速排序算法。
RTree = record
sParent : string[6];
sChild : string[6];
end;var
aTree : array of RTree;procedure TZFMF.FormShow(Sender: TObject);
var
i : integer;
begin
Query.open;
setlength(aTree,Query.RecordCount);
first;
i := 0;
with Query do
begin
aTree[i].sParent := FieldByName('Parent').AsString;
aTree[i].sChild := FieldByName('Child').AsString;
inc(i);
Next;
end;
BuildTree(nil,'001');
end;procedure BuildTree(var ParentNode: TTreeNode;Parent: string);
var
myNode: TreeNode;
begin
myNode := ParentNode;
for i:=Low(aTree) to High(aTree) do
begin
if aTree[i].sParent=Parent then
begin
if myNode=nil then
ParentNode := TreeView1.Items.Add(nil,aTree[i].sChild)
else
ParentNode := TreeView1.Items.AddChild(myNode,aTree[i].sChild);
BuildTree(ParentNode,aTree[i].sChild);
end;
end;
end;如果你的数据取出是有序的,则你还可以节约一半的比较Parent的时间!
liang_z(千山一刀之忍者神龟) :我只是读一次数据库, 时间又怎会浪费在读取数据库上呢?真的是浪费在算法上, 我的做法就是你的做法了, 不过我是读取到stringList上, 而不是动态数组中, 不过就是因为每做一次都要遍历一次stringlist中所有的内容, 时间就是浪费在这里
那就是你的搜索算法的问题,当你读入的时候进行Order by,你的SQL里面这句已经做了,你的搜速算法可以采用2分查找来做的,10000,大约log2 10000 次就可找到了,不会超过40次比较的!
你说得对了, 就是这样, 我现在就是想改进一下这里
我在取数据前用了order by ,可以节省一半的比较,不过我
想这不是主要的!关键还是插入节点是费时了,
不过你的程序还用了一个费时的函数就是IndexOf,
我想这个函数还是不用的好!你用我的方法试一下,我到少会在
10秒钟之内做完,不过这还不是根本的办法,
根本的办法应该是展开什么节点就建立起它的子节点!
我想它将使你的速度慢上好1、2倍。