【问题标题】:Finding all objects of type T in a tree structure C#在树结构 C# 中查找所有类型为 T 的对象
【发布时间】:2009-04-09 07:44:03
【问题描述】:

我需要编写一个树搜索方法,它接受一个类型参数 T 并返回树中存在的所有类型 T 的项目。有没有办法做到这一点?在这一点上,我更喜欢优雅而不是效率......

【问题讨论】:

    标签: c# generics search tree


    【解决方案1】:

    类似这样的:

    internal static IEnumerable<T> AllDescendantNodes<T>( this TreeNode input ) 
        where T class;
    {
        T current = null;
        foreach ( TreeNode node in input.Nodes )
            if( (current = node as T) != null )
            {
                yield return current;
                foreach ( var subnode in node.AllDescendantNodes<T>() )
                    yield return subnode;
            }
    }
    

    然后您可以将其作为扩展方法针对根节点调用:

    foreach( MyCustomNodeClass item in rootNode.AllDescendantNodes<MyCustomNodeClass>() ) 
    {
        ...
    }
    

    【讨论】:

    • 这对我有用。我还不了解扩展方法,因此不确定它是否有效。但这是一个优雅的解决方案。从我看到的情况来看,只检查给定输入的后代。我必须修改 AllDescendants 以检查输入节点类型并生成它。谢谢
    • 其实我需要创建一个特殊的根节点,然后传入。修改AllDescendants是错误的。谢谢
    • 扩展方法在编译时被转换为正常的静态调用——使用它们对性能没有影响。这个方法处理递归,所以我可能有一个类似的方法在树的根节点上工作,然后调用它。
    • 使用显式堆栈而不是递归的方法可能性能稍好一些,但我不会担心这一点,除非您拥有具有数百万个节点的树。
    【解决方案2】:

    嗯,在内部,该方法必须遍历树的所有元素,因此跳过仅枚举它,并使用 OfType LINQ 方法并没有那么远:

    var onlyTs = yourTree.OfType<SomeT>();
    

    【讨论】:

    • +1 给出正确答案 :) 刚刚意识到我错过了重点
    【解决方案3】:

    假设你的树是通用的。即Item&lt;T&gt;

    int count = yourTree.Count(p => p == typeof(T));
    

    否则,解析每个节点并比较“item == typeof(T)

    【讨论】:

      【解决方案4】:

      您需要的是一个基本的树遍历函数(前序、中序或后序——这无关紧要)和一个过滤器函数。然后你可以将这两者组合在一起,得到你需要的东西:

      IEnumerable<T> Traverse(Tree<T> tree)
      {
          yield return tree.Data;
      
          foreach(Tree<T> subtree in tree.Subtrees)
              foreach(T t in Traverse(subtree))
                  yield return t;
      }
      
      IEnumerable<U> Filter<T, U>(IEnumerable<T> source)        
          where U : T
      {
          foreach(T t in source)
              if(t is U)
                  yield return (U)t;
      }
      

      【讨论】:

      • 与我的想法相似,但我会做一个更改:您要进行两次转换 - t as U 并且检查 null 比 if( t is U ) (U) t 更快;
      猜你喜欢
      • 1970-01-01
      • 2010-09-25
      • 2012-05-26
      • 2021-01-04
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 1970-01-01
      相关资源
      最近更新 更多