C# 如何使树节点的值成为IEnumerable?
考虑以下类别:C# 如何使树节点的值成为IEnumerable?,c#,ienumerable,lazy-evaluation,C#,Ienumerable,Lazy Evaluation,考虑以下类别: class TreeNode { int value; public TreeNode l, r; public TreeNode(int value) { this.value = value; } public IEnumerable<int> sub_values() { if (l != null) foreach (int i in l.sub_v
class TreeNode
{
int value;
public TreeNode l, r;
public TreeNode(int value)
{
this.value = value;
}
public IEnumerable<int> sub_values()
{
if (l != null)
foreach (int i in l.sub_values())
yield return i;
if (r != null)
foreach (int i in r.sub_values())
yield return i;
yield return value;
}
}
类树节点
{
int值;
公共树状体l,r;
公共树节点(int值)
{
这个值=值;
}
公共IEnumerable子_值()
{
如果(l!=null)
foreach(l.sub_值()中的int i)
收益率i;
如果(r!=null)
foreach(r.sub_值()中的int i)
收益率i;
收益回报值;
}
}
每个值被传递O(h)
次,其中h
是树的高度。首先,在中生成返回值代码>语句,然后在中产生返回i每个父节点的代码>
因此,sub_值
使用O(nh)
时间复杂度返回n
值
我可以用一个方法代替它,它接受对整数列表的引用,而不是返回值,将它们添加到这个列表中,但它不再是懒惰的
我可以在O(n)
中返回n
值并保持惰性吗?这与其他关于递归迭代器的SO帖子非常相似。所有这些都涉及使用显式堆栈或队列。以下是适用于任何类型树的通用解决方案。让我们首先在一些公共位置定义一个可重用函数,以便下次
请注意遍历
方法-它提供了您所要求的惰性。现在,您可以使用常用的LINQ方法进行过滤、投影等。例如,所讨论的方法如下
public IEnumerable<int> sub_values()
{
return Traverse().Select(node => node.value);
}
public IEnumerable sub_值()
{
返回遍历().Select(node=>node.value);
}
public bool AnyChildren() { return l != null || r != null; }
public IEnumerable<TreeNode> Children
{
get
{
if (l != null) yield return l;
if (r != null) yield return r;
}
}
public IEnumerable<TreeNode> Traverse(bool preOrder = false)
{
return TreeHelper.Traverse(this, node => node.AnyChildren() ? node.Children : null, preOrder);
}
public IEnumerable<int> sub_values()
{
return Traverse().Select(node => node.value);
}