代码之家  ›  专栏  ›  技术社区  ›  Bryan

如何从给定父节点的树中获取随机项?

  •  0
  • Bryan  · 技术社区  · 14 年前

    我有一个场景,我想随机化一些项目的显示。对于父项,如何随机选择其子项之一?

    当然,我可以加载所有的孩子,并应用一些随机索引或其他什么…但这将是非常低效的。

    我想知道这是否也是低效的:

    parent.children[随机(parent.children.count)]?

    访问parent.children时,在什么时候加载这些项?

    2 回复  |  直到 11 年前
        1
  •  3
  •   Bartłomiej Mucha    11 年前

    children是一个懒惰的加载属性,我绝对不建议以您在此处显示的方式使用它。

    在发布这篇文章之前,我对API进行了一些挖掘,看看是否真的没有一种方法可以在不加载此属性的情况下计算子项,但遗憾的是,我真的找不到任何看起来“合法”的方法。只有.hasschildren属性似乎是相关的,而且它似乎通过完成.children属性已经完成的大部分(但不是全部)工作。

    但是,考虑到它是延迟加载的,为了最大限度地提高效率,请将属性的结果存储在私有字段中。我记得曾经在官方的开发者指南中读过这个,如果需要的话,我可以挖掘出确切的参考。

    ChildList itemChildren = myItem.Parent.Children;
    // Continue doing random() etc here, but using the itemChildren field.
    
        2
  •  0
  •   Vivin Paliath    14 年前

    你手头上有整棵树吗?然后你可以做一些随机遍历。例如,可以从二进制树中选择一个随机项,如so(伪代码):

    sub randomNode(node):
       randomVal = random(0, 3); // random value between 0 and 3
    
       if(randomVal == 0):
         return randomNode(node.left) if node.left != null else return node;
       elseif(randomVal == 1):
         return randomNode(node.right) if node.right != null else return node;
       else
         return node;
    

    对于n元树,可以有如下内容:

    sub randomNode(node):
       randomVal = random(0, 2)
    
       if(randomVal == 0):
         return randomNode(node.children[random(0, node.children.length)]) if node.children.length != 0 else return node;
       elseif(randomVal == 1):
         return node;
    

    parent.children[random(parent.children.count)] 在我看来效率并不低,这是我在上面的算法中使用的。至于最后一个问题,我想这取决于您如何实现树。如果你自己建立了一个树结构,那么你必须拥有整个树结构。如果您使用的是框架,那么它取决于该框架的实现。