我想对n元树数据结构进行折叠。 (倍是又名聚集在LINQ)
我设法拿出一个工作液:如何在C中折叠n元树#
public static R Aggregate<T, R>(T node,
Func<T, IEnumerable<T>> getChildren,
Func<T, IEnumerable<R>, R> aggregator)
{
var childResults = getChildren(node)
.Select(c => Aggregate(c, getChildren, aggregator));
return aggregator(node, childResults);
}
getChildren
是定义如何让一个给定节点的孩子FUNC。它必须为叶节点返回一个空的IEnumerable。
aggregator
定义了如何使用当前节点及其子节点的结果来处理节点。
的解决方案似乎工作,但也存在一些问题:
的算法是递归的,它会吹栈对于很深的树。
如何重写函数以防止堆栈溢出?该算法是懒惰的,但只有一种。
例如如果aggregator
仅使用子节点的Enumerable.First
结果,则只遍历树的最左侧分支。然而,与Enumerable.Last
整个树被遍历,即使只需要最右边的分支进行计算。
我该如何让算法真的很懒惰?
F#解决方案欢迎,但C#首选。
当你最初建的树,你不是有一个深筹码?那么为什么当这个算法在构建树的时候已经有了n-deep的堆栈的时候,这个算法会打碎堆栈呢? – philologon
@philologon:整个树不一定在内存中。一个例子就是一个网络爬虫。 – 3dGrabber
使用延续或蹦床。 –