过滤层次结构列表并保留路径

时间:2015-07-24 20:14:40

标签: c# hierarchy depth-first-search

在C#中,我如何搜索层次结构列表并在结尾处保持路径完整。例如:

对象

public class Node
{
    public IEnumerable<Node> Children { get; set; }

    public string Id { get; set; }
}  

结果

  • 一个
    • AA
      • AAA
      • AAB
  • b
    • BA
    • BB
      • BBA

我想要什么

如果我在此列表中搜索单词&#34; aab&#34;,我想将此结果显示给客户:

  • 一个
    • AA
      • AAB

我发现搜索层次结构列表的一个实现是https://stackoverflow.com/a/30907231/316759,但问题是它只返回找到的叶节点而不保留层次结构。

public static T DepthFirstSearch<T, TChilds>(this T node, Func<T, TChilds> ChildsProperty, Predicate<T> Match) where T : class
{
    Stack<T> stack = new Stack<T>();
    stack.Push(node);

    while (stack.Count > 0)
    {
        T thisNode = stack.Pop();

        if (Match(thisNode))
        {
            return thisNode;
        }

        if (ChildsProperty(thisNode) != null)
        {
            foreach (T child in (ChildsProperty(thisNode) as IEnumerable<T>).Reverse())
            {
                stack.Push(child);
            }
        }
    }

    return null;
}

我需要的是找到叶子节点并让他们的父母保持根。

2 个答案:

答案 0 :(得分:0)

这是一个快速示例,可让您标记所需的节点,如下所示:

public bool NodeOrChildrenMatch(Node n)
{
    if (IsMatch(n))
    {
        Show(n);
        return true;
    }
    else
    {
        if (n.Children.Any(NodeOrChildrenMatch))
        {
            Show(n);
            return true;
        }
        return false;
    }
}

答案 1 :(得分:0)

近似代码 - 在递归时收集“路径”并在上升时清理最后一个元素:

Stack<T> path = new Stack<T>();
public static bool DepthFirstSearch(T node, Stack<T> path, Predicate<T> Match) 
{
    path.Push(node);

    if (Match(node))
        return true;

    foreach (T child in (thisNode.Children)
    {
         if (DepthFirstSearch(child, stack, Match))
              return true;
    }

    stack.Pop();
    return false;
}