2012-02-03 43 views
9

我有返回所有子树节点递归函数,给定的起始根节点。递归与产量返回元件订购树

private IEnumerable<Node> getAllNodesRecursively(Node subnode) 
{ 
    foreach (Node node in subnode.Nodes) 
     getAllNodesRecursively(node); 

    yield return subnode; 
} 

对于下面的树结构:

A 
| 
+--B 
| 
+--C 
| | 
| +--D 
| 
+--E 

当我试图重复这样:

foreach (Node n in getAllNodesRecursively(a)) 
{ 
    Console.WriteLine(n); 
} 

函数返回只有一个值。

我希望使用的产量返回递归和检索在预订元件(A,B,C,d,E在此实例中)。

(如果我把之前的foreach产量的回报,在foreach永远不会发生)。

这可能吗?

+0

您是否尝试过,如果您将收益率回报在前面,则不调用该foreach?我想它会被调用。 – okrumnow 2012-02-03 09:55:56

+0

是的,你是对的。收益率回报不会跳过其余的代码。看起来它只是一种允许价值回归并保持功能运行的语法糖。我的错。 – 2012-02-03 10:24:47

回答

16

你有没有尝试过这样的:

private IEnumerable<Node> getAllNodesRecursively(Node subnode) 
{ 
    // Return the parent before its children 
    yield return subnode; 

    foreach (Node node in subnode.Nodes) 
    { 
     foreach(Node n in getAllNodesRecursively(node)) 
     { 
      yield return n; 
     } 
    } 
} 

你的实现是调用getAllNodesRecursively递归,但忽略它的返回值。

+0

这有效,但为什么我必须重新迭代(内部foreach)?为什么迭代器方法不允许递归?我试过用调试器,它只是跳过我的递归调用,除非它在迭代中使用(如foreach)。这是为什么? – 2012-02-03 10:20:50

+0

@ChristianHayter“除了顶部节点两次之外,不会返回所有内容吗?” – Joe 2012-02-03 10:28:42

+1

乔的例子可以由号稍微简化:私人的IEnumerable getAllNodesRecursively(节点根) { 收率返回根; 的foreach(在root.Nodes.SelectMany(getAllNodesRecursively VAR子)){ 产量 回孩子; } } – peter70 2014-07-24 09:55:15

3

是的,这是可能的,只是把yield return之前foreach。您正在考虑正常的return声明的行为。

+0

我修改了我的帖子,因为我错了会显示什么内容。只有第一个元素被返回。如果我在foreach之前提供收益回报,则会发生同样的情况。怎么来的? – 2012-02-03 10:04:41

+0

嗯。我现在无法自己尝试。您是否尝试过使用调试器单步执行代码? – 2012-02-03 10:09:11

+0

调试器只是跳过递归调用。这很有趣。 – 2012-02-03 10:17:55

1
 public IEnumerable<int> preOrder(Node root) 
     { 
      if (root == null) 
       yield break; 

      yield return root.val; 

      if (root.left != null) 
       foreach (int i in preOrder(root.left)) 
        yield return i; 

      if (root.right != null) 
       foreach (int i in preOrder(root.right)) 
        yield return i; 
     } 
+0

虽然此代码段可以解决的问题,[包括一个解释](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers)确实有助于提高质量您的帖子。请记住,您将来会为读者回答问题,而这些人可能不知道您的代码建议的原因。 – lokusking 2016-08-14 12:06:39