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

时间:2010-02-11 16:04:02

标签: c# .net recursion

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

测试树

A1(checked) -> B1(unchecked)
A2(checked)
A3(checked)

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

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

6 个答案:

答案 0 :(得分:20)

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

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

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

答案 1 :(得分:8)

更改:

AllNodesChecked(node.Nodes); 

要:

if(!AllNodesChecked(node.Nodes))
    return false;

答案 2 :(得分: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);
    }
}

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

bool allChecked = root.AllNodes().All(x=>x.Checked);

没有递归,没问题。

答案 3 :(得分:3)

您没有评估递归调用检查子节点的结果。

答案 4 :(得分:2)

试试这个:

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

答案 5 :(得分:-1)

我必须加上我的两分钱......学习函数式编程恕我直言。

public static bool AllNodesChecked(TreeNodeCollection nodes)  
{
    return nodes.All(i => i.Checked && AllNodesChecked(i.Nodes));
}