【问题标题】:VirtualTreeview: when to sort children?VirtualTreeview:何时对孩子进行排序?
【发布时间】:2010-03-10 03:39:54
【问题描述】:

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

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

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

【问题讨论】:

    标签: delphi sorting tree virtualtreeview


    【解决方案1】:

    这种场景的一般规则是在所有新项目都添加后进行排序。这样您只需排序(和初始化)一次。

    【讨论】:

    • 没有“新”项目可言。树只是简单地修改和重建(因为在我的例子中支持树的数据结构完全改变了)。
    • “重建”树相当于创建一个新树。原理是一样的:暂停排序,开始构建,添加所有节点,结束构建,然后排序。
    【解决方案2】:

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

    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 步骤中完成加载项目。在树中,每当你匹配时,你都会为孩子们运行类似的例程。这个概念与现有列表中的项目不会发生太大变化或完全加载可能很昂贵的事实相权衡。

    【讨论】:

    • 感谢您的详细回答,但 VirtualTreeView 速度如此之快,简单的清除/重新加载策略似乎就足够了。 (显然除了排序之外:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 2017-06-26
    • 2017-11-07
    • 2018-10-11
    • 2018-03-22
    • 2013-01-01
    相关资源
    最近更新 更多