【问题标题】:Get all Child of Node获取节点的所有子节点
【发布时间】:2021-05-24 21:56:45
【问题描述】:

我在下面有一个Node 类:

public class Node {
        public int begin {get;set;}
        public int end {get;set;}
    }

然后我创建一个包含父母和孩子的列表,如下所示:

List<Node> list = new List<Node>();
list.Add(new Node(){begin = 1, end =2});
list.Add(new Node(){begin = 1, end =3});
list.Add(new Node(){begin = 2, end =4});
list.Add(new Node(){begin = 2, end =5});
list.Add(new Node(){begin = 5, end =6});
list.Add(new Node(){begin = 5, end =7});

这是上面列表的树数据:

        1
    2      3
  4   5
     6 7

如何找到节点的所有父节点? 例如,如果我的Node2。结果是:4,5,6,7

我尝试了这段代码,但当我的Node2 时,结果只有4 , 5

    public static List<int> FindChild(List<Node> list,int id) {
      int value = id;
        List<int> res = new List<int>();

      var child = list.Where(b => b.begin == id).ToList();
      foreach (var item in child) {
          res.Add(item.end);
          FindChild(list,item.end);
      }

      return res;
}

【问题讨论】:

  • 好的,所以你没有节点列表,你有列表。您可能想重命名您的课程以反映这一点!不管怎样,问题是你忽略了FindChild的返回值——你可能想要res.AddRange(FindChild(list, item.end));
  • 将父级添加到您的节点类并在初始化每个节点时添加父级。
  • @Orace 另一个问题不相关——它建立在有父节点​​的节点上,而这个问题建立在边缘上。 OP 自己也几乎解决了这个问题,而您提出的副本并不能帮助他们完成最后一步

标签: c#


【解决方案1】:

正如 canton7 在 cmets 中提到的,您使用的是边而不是节点。

除此之外,您当前没有在递归 FindChild 调用中添加每个项目到 res

与使用列表相比,使用IEnumerable 会更高效/更灵活:

public static IEnumerable<int> FindDescendants(IEnumerable<Edge> edges, int id)
{
    var children = edges.Where(b => b.begin == id);
    foreach (var child in children)
    {
       yield return child.end;
       foreach (var descendant in FindDescendants(edges, child.end))
       {
           yield return descendant.end;
       }
    }
}

如果需要列表,可以使用 LINQ:

List<int> descendants = FindDescendants(list, 2).ToList();

【讨论】:

    【解决方案2】:

    你真的很亲密!

    您正确地找到了所有以 2 为父级的边,并且您正确地递归遍历了 2 的所有子级以找到 它们的子级。唯一的问题是您正在丢弃这些信息!

    public static List<int> FindChild(List<Node> list,int id) {
        int value = id;
        List<int> res = new List<int>();
    
        var child = list.Where(b => b.begin == id).ToList();
        foreach (var item in child) {
            res.Add(item.end);
            FindChild(list,item.end); // <-- You threw away the return value!
        }
    
        return res;
    }
    

    最简单的解决方案就是将FindChild的返回值加到res

    res.AddRange(FindChild(list,item.end));
    

    这个works


    您可以稍微提高效率,并避免创建大量新列表并复制其内容:

    public static List<int> FindChild(List<Node> input, int id)
    {
        var result = new List<int>();
        FindChild(input, id, result);
        return result;
    }
    
    public static void FindChild(List<Node> input, int id, List<int> result) {
        int value = id;
    
        var child = input.Where(b => b.begin == id).ToList();
        foreach (var item in child) {
            result.Add(item.end);
            FindChild(input, item.end, result);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多