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

如何使用LINQ从树中的所有节点获取列表?

  •  2
  • Homam  · 技术社区  · 14 年前

    如何使用LINQ从树中的所有节点获取列表?

    我的课程是:

    class Node
    {
     public class Node()
     {
      Children = new List<Node>();
     }
    
     public List<Node> Children { get; set;}
    }
    
    class Tree
    {
     public Tree()
     {
      Roots = new List<Node>();
     }
    
     List<Node> Roots { get; set;}
    }
    
    3 回复  |  直到 14 年前
        1
  •  3
  •   Ani    14 年前
    class Node
        {
        public Node()
        {
            Children = new List<Node>();
        }
    
        public IEnumerable<Node> GetSubTree()
        {
            return Children.SelectMany(c => c.GetSubTree()).Concat(new[] { this });
            //Post-order traversal
        }
    
        public List<Node> Children { get; set; }
    }
    
    class Tree
    {
        public Tree()
        {
            Roots = new List<Node>();
        }
    
        public IEnumerable<Node> GetAllNodes()
        {
            return Roots.SelectMany(root => root.GetSubTree());
        }
    
        List<Node> Roots { get; set; }
    }
    

    一棵树怎么能有多个根呢?这不是森林吗?

        2
  •  3
  •   LukeH    14 年前
    var allNodes = yourTree.Roots.SelectMany(x => x.TraverseTree(y => y.Children));
    
    // ...
    
    public static class EnumerableExtensions
    {
        public static IEnumerable<T> TraverseTree<T>(
            this T parentNode, Func<T, IEnumerable<T>> childNodesSelector)
        {
            yield return parentNode;
    
            IEnumerable<T> childNodes = childNodesSelector(parentNode);
            if (childNodes != null)
            {
                foreach (T childNode in
                    childNodes.SelectMany(x => x.TraverseTree(childNodesSelector)))
                {
                    yield return childNode;
                }
            }
        } 
    }
    
        3
  •  1
  •   Anton Gogolev    14 年前

    您可以通过添加 traversal method ,或通过使用 recursive LINQ with Y-combinator . 我个人更喜欢第一种方法。