这种类型的可枚举操作是否有可接受的名称?

时间:2011-06-23 07:43:39

标签: c# linq terminology list-comprehension

我经常发现自己需要遍历分层对象的树,并在整个过程中对每个项目执行操作。在列表理解白话中,这种操作是否有一个普遍接受的名称?我问,因为我记得在.net框架中有一个等价物并且认为它有一个不寻常但恰当的名称之前,首先要了解python的zip function

以下是一些通用的方法,可以在树形结构中上下移动,并在遇到每个项目时生成它们。

public static IEnumerable<T> Ancestors<T>(T source, Func<T, T> selector)
{
    do
    {
        yield return source;
        source = selector(source);
    } while (!Equals(source, default(T)));
}

public static IEnumerable<T> Descendents<T>(T source,
                                            Func<T, IEnumerable<T>> selector)
{
    var stack = new Stack<T>();
    stack.Push(source);
    while (stack.Count > 0)
    {
        source = stack.Pop();
        yield return source;
        var items = selector(source);
        if (items != null)
        {
            foreach (var item in items)
            {
                stack.Push(item);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:7)

假设选择器给出了子节点,你的第二种方法是“正确的第一个深度优先”遍历。也就是说,如果你有

      A
    /  \
   B     C
  / \   / \
 D   E F   G

然后你得到A,C,G,F,B,E,D。你在“B”之前得到“G”,因为“深度优先”在它尝试另一个分支之前会尽可能地深入。在你的特定例子中,你会在B之前得到C,因为它优先于左边。

如果您将其更改为

foreach (var item in items.Reverse())  

然后你会得到一个左先深度优先遍历,这是大多数人对深度优先遍历的看法。

如果您将堆栈更改为队列,那么它将成为“广度优先”遍历。 A,B,C,D,E,F,G。你一次做一整个“水平”。

还有其他遍历。请注意,深度优先和广度优先搜索都具有父节点位于子节点之前的属性。您还可以进行“后期订单”遍历,其中每个节点都在其子节点之后。

二叉树也有“顺序”遍历。这棵树的顺序遍历是D,B,E,A,F,C,G。也就是说,每个左边的孩子都来自它的所有祖先,每个正确的孩子都来自它的祖先。作为练习,你能在二叉树上编写有序遍历吗?

答案 1 :(得分:1)

这些是标准Tree Traversal函数,通常也称为“树行走”。很难给出你的例子标准名称,因为具体的步行策略是未知的:)