为什么这个递归不能在C#中运行?

Iai*_*der 3 .net c# recursion

public static bool AllNodesChecked(TreeNodeCollection nodes)        
{
    foreach (TreeNode node in nodes)
    {
        if (!node.Checked)
        {
            return false;
        }
        AllNodesChecked(node.Nodes);
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

测试树是

A1(checked) -> B1(unchecked)
A2(checked)
A3(checked)
Run Code Online (Sandbox Code Playgroud)

但是当它到达节点B1时它不会返回.

编辑:谢谢大家帮助我疲惫的大脑.只能在冷水淋浴后的第二天早些时候尝试递归.

Meh*_*ari 20

您忽略AllNodesChecked递归调用中的返回值:

public static bool AllNodesChecked(TreeNodeCollection nodes)        
{
    foreach (TreeNode node in nodes)
        if (!node.Checked || !AllNodesChecked(node.Nodes))
           return false;
    return true;
}
Run Code Online (Sandbox Code Playgroud)

return语句仅从调用堆栈中的当前方法返回到直接调用方.它不会突然从调用堆栈中的所有其他调用返回.

  • +1不将布尔值与文字进行比较! (3认同)

Kla*_*sen 8

更改:

AllNodesChecked(node.Nodes); 
Run Code Online (Sandbox Code Playgroud)

至:

if(!AllNodesChecked(node.Nodes))
    return false;
Run Code Online (Sandbox Code Playgroud)


Eri*_*ert 7

我会采取略微不同的方法.我要做的是我首先编写的代码将你的树(我认为它真的是一棵树,而不是任意图形)变成一系列节点.就像是:

static IEnumerable<Node> AllNodes(this Node node)
{
    var stack = new Stack<Node>();
    stack.Push(node);
    while(stack.Count > 0)
    {
        var current = stack.Pop();
        yield return current;
        foreach(var child in current.Nodes)
            stack.Push(child);
    }
}
Run Code Online (Sandbox Code Playgroud)

现在您可以使用序列运算符:

bool allChecked = root.AllNodes().All(x=>x.Checked);
Run Code Online (Sandbox Code Playgroud)

没有递归,没问题.

  • 我认为递归是解决这类"树"问题的更自然和可读的方法(除非预期树大于调用堆栈可以容纳的). (3认同)
  • @Mehrdad:我同意,在递归数据结构上使用递归更为优雅.然而,(1)缺乏尾递归,(2)堆栈爆炸时的灾难性故障,(3)递归迭代器块效率低下,(4)序列运算符摇摆不定.这些要点促使我走向迭代解决方案,将递归数据结构重新解释为非结构化序列. (2认同)