我的数据库结构
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;

解决方案 »

  1.   

    shuixin13(犬犬(心帆)) ,如果是这样怎样判断还有没有下一层呀
      

  2.   

    首先,这个TreeView 我想不会有人想完全察看,一般都是看一部分,看自己需要的部分。开始的时候一般都是未展开的。看哪个展开哪个。
    我们能不能这么做,开始的时候只建立父一级及其儿子,孙子、重孙子县不予考虑。如果想展开那一层的儿子,那么在建立他的儿子的儿子。
    这样避免了建立整棵树。主要思想就是看哪个分枝就建立哪个分支,不看得不建立。
      

  3.   

    先将第一层查询出来,当用户点击一个分支时,再查出属于这个分支的第二层分支,这是个好主意,看多少算多少,大多数软件都是这样的,Windows自己也是的,浏览到哪里就查询哪里的文件和目录
      

  4.   

    我想这种情况速度和算法关系不大吧
    节点还没有展开的时候那个节点的数据又看不到,所以在树节点展开的时候(OnExpanding)再载入数据会好一点,可以分流一些数据,不要一次性就把所有的数据装载到树结构
      

  5.   

    多线程改变不了计算的速度的,一个办法是分段读取,当展开那个节点的时候再读取。还一个办法将数据一次性读入内存,在内存中操作比你使用SQL 语句来的快些,可以在读入的时候进行排序,在查找子节点的时候使用二分查找,这样能够提高速度,但是对内存要求高些。自己决断该使用哪些方法。
    ----------------------------------
    一个排序的小技巧:
    当你定义类或者指针的时候可以使用TList作为容器来保存结果,然后写一个回调的判断你的对象或者指针的优先级,这样可以使用TList的快速排序算法。
      

  6.   

    读入的时候可以使用order by进行排序先会快很多!
      

  7.   

    type 
      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的时间!
      

  8.   

    多谢各位关注。
    liang_z(千山一刀之忍者神龟) :我只是读一次数据库, 时间又怎会浪费在读取数据库上呢?真的是浪费在算法上, 我的做法就是你的做法了, 不过我是读取到stringList上, 而不是动态数组中, 不过就是因为每做一次都要遍历一次stringlist中所有的内容, 时间就是浪费在这里
      

  9.   

    千万注意,如果你的TREE设置了自动展开,则你的建树速度会慢上几十倍!
      

  10.   

    : hansonboy(良) (  )
    那就是你的搜索算法的问题,当你读入的时候进行Order by,你的SQL里面这句已经做了,你的搜速算法可以采用2分查找来做的,10000,大约log2 10000 次就可找到了,不会超过40次比较的!
      

  11.   

    hansonboy(良) (  ) :
    你说得对了, 就是这样, 我现在就是想改进一下这里
      

  12.   

    我建一个一百个节点的TREE几乎不花时间,至少我感觉不到!
    我在取数据前用了order by ,可以节省一半的比较,不过我
    想这不是主要的!关键还是插入节点是费时了,
    不过你的程序还用了一个费时的函数就是IndexOf,
    我想这个函数还是不用的好!你用我的方法试一下,我到少会在
    10秒钟之内做完,不过这还不是根本的办法,
    根本的办法应该是展开什么节点就建立起它的子节点!
      

  13.   

    我发现你用了两个IndexOf,
    我想它将使你的速度慢上好1、2倍。