2

我依靠 VirtualTreeView 来显示数以千计的项目,这些项目偶尔会发生变化,当这种情况发生时,树会被清理并再次填充。

排序是自动完成的(toAutoSort标志集),但这会产生递归初始化所有节点的不良影响,这是一个非常昂贵的操作,您可以想象。

那么何时应该在关闭时调用该.Sort方法toAutoSort?(DoInitChildren 看起来很合理,但我偶尔会得到奇怪的结果,比如颠倒的结果,所以我认为这不是对孩子进行分类的好事件。)

4

2 回答 2

4

这种情况下的一般规则是在添加了所有新项目后进行排序。这样你只排序(和初始化)一次。

于 2010-03-10T03:54:51.533 回答
1

除非整个树每次都完全不同,否则你可以通过不清除树来获得更好的性能,而是单独构建一个新的项目列表(只是项目的标识),对该列表进行排序,然后按顺序遍历两棵树。 . 一般算法看起来像这样(左列表是“新列表”,右列表是“现有列表”):

LeftCur := 0;
RightCur := 0;
while (LeftCur < TotalLeft) and (RightCur < TotalRight) then
  begin
    if LeftList[LeftCur] = RightList[RightCur] then
      begin
        // matches, so just advance 
        Inc(LeftCur);
        Inc(RightCur);            
      end
    else if LeftList[LeftCur] < RightList[RightCur] then
      begin
        // insert happens BEFORE RightCur
        InsertLeftItemToRight;
        Inc(RightCur);
        Inc(TotalRight);
      end
    else if LeftList[LeftCur] > RightList[RightCur] then
      begin
        DeleteRightItem;
        Dec(TotalRight);
      end;
  end;
  While RightCur < TotalRight do
    begin
      DeleteRightItem;
      Dec(TotalRight);
    end;
  While LeftCur < TotalLeft do
    AppendLeftItemToRight;

这样,列表保持排序状态,您只需在 InsertLeftItemToRight 步骤中完成加载项目。在树中,每当你匹配时,你都会为孩子们运行类似的例程。这个概念与现有列表中的项目不会发生太大变化或完全加载可能很昂贵的事实相权衡。

于 2010-03-10T17:02:01.453 回答