【发布时间】:2013-03-27 14:26:21
【问题描述】:
下面的代码有效,但我想避免使用递归。 ListOfAllNodes 是数据库中所有节点的平面列表,包含 Id 和 ParentId 字段。
private Node FillChildNodes(Node node)
{
foreach (var childNode in ListOfAllNodes.Where(i => i.ParentId == node.Id).OrderBy(x => x.Name))
{
node.Children.Add(childNode);
FillChildNodes(childNode);
}
return node;
}
【问题讨论】:
-
为什么要避免递归?递归并不邪恶!在某些情况下使用它是有意义的,这就是其中之一!
-
我要做的改进是一次性将平面列表预处理成字典,而不是在每次调用 FillChildNodes 时重新解析它
-
您可以在第一遍中使用以键作为节点 ID 并以值作为节点的字典,并始终在第二遍中从字典中查找父节点。另外,您是否假设数据有效(没有循环,所有节点都有父节点)?
-
是否存在递归堆栈溢出错误的固有风险?
-
@JAG:每次
new生成对象时,都有出现 OOM 错误的风险。你不会避开物体,是吗?不,因为它们很有用。与递归一样,如果您负责任地使用它。如果你真的很担心,你可以很容易地包含一个深度参数,并在超过深度时抛出一个异常......但是 SO 会做同样的事情,并且不那么随意。