首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >递归集合搜索

递归集合搜索
EN

Stack Overflow用户
提问于 2013-07-13 21:17:11
回答 3查看 720关注 0票数 1

我有一个对象集合(List<Element>),如下所述:

代码语言:javascript
复制
class Element
{
  string Name;
  string Value;
  ICollection<Element> ChildCollection;
  IDictionary<string, string> Attributes;
}

我基于读入的一些XML构建了一个Element对象的List<Element>集合,我对此非常满意。如何实现对这些元素的搜索目前对我来说并不困惑,但我想知道是否有更好的解决方案。

该集合的结构如下所示:

代码语言:javascript
复制
- Element (A)
  - Element (A1)
    - Element (A1.1)
  - Element (A2)
- Element (B)
  - Element (B1)
    - Element (B1.1)
    - Element (B1.2)
- Element (C)
  - Element (C1)
  - Element (C2)
  - Element (C3)

目前,我正在使用递归在每个顶级(A,B,C) ElementAttributes字典中搜索特定的KeyValuePair。如果我在顶层Element中找不到它,我就开始搜索它的ChildElement集合(1,1.1,2,2.1,n等)。以同样的方式。

我好奇的是,是否有更好的方法在这些对象上实现搜索,或者在这种情况下递归是更好的答案,如果我应该像现在一样实现搜索,top -> child -> child ->等,还是应该以其他方式搜索,比如先搜索所有顶级?

我可以使用TPL并行搜索每个顶级(A、B、C)吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-13 21:25:39

递归是实现按深度优先顺序访问元素的树搜索的一种方式。您可以使用循环而不是递归来实现相同的算法,方法是使用堆栈数据结构来存储需要访问的树的节点。

如果对队列而不是堆栈使用相同的算法,则搜索将以呼吸优先的顺序进行。

在这两种情况下,一般算法如下所示:

代码语言:javascript
复制
var nodes = ... // some collection of nodes
nodes.Add(root);
while (nodes.Count != 0) {
    var current = nodes.Remove ... // Take the current node from the collection.
    foreach (var child in current.ChildCollection) {
        nodes.Add(child);
    }
    // Process the current node
    if (current.Attributes ...) {
        ...
    }
}

请注意,该算法不是递归的:它使用显式的nodes集合来保存搜索的当前状态,而递归实现则使用调用堆栈来实现相同的目的。如果nodesStack<Element>,则搜索在depth-first order中进行;如果nodesQueue<Element>,则搜索在breadth-first order中进行。

票数 1
EN

Stack Overflow用户

发布于 2013-07-13 21:25:27

您可以重用专为以不同方式遍历而设计的现有组件,例如NETFx IEnumerable.Traverse Extension Method。它允许您首先选择深度或广度。它允许您首先遍历可枚举树,深度或广度。

获取平面化的目录枚举表的示例:

代码语言:javascript
复制
IEnumerable<DirectoryInfo> directories = ... ;

IEnumerable<DirectoryInfo> allDirsFlattened = directories.Traverse(TraverseKind.BreadthFirst, dir => dir.EnumerateDirectories());

foreach (DirectoryInfo directoryInfo in allDirsFlattened)
{
    ...
}

对于BreadhFirst,它在内部使用Queue<>,对于DepthFirst,它在内部使用Stack<>

它不是并行遍历节点,除非遍历是需要资源的,否则在这个级别上使用并行化是不合适的。但这取决于上下文。

票数 0
EN

Stack Overflow用户

发布于 2013-07-13 21:33:08

我从某个地方抓取了这个比特,它不是我的,但我无法提供它的链接。这个类为递归搜索展平了一个树形视图,看起来它也应该为你做同样的事情。

代码语言:javascript
复制
public static class SOExtension
{
    public static IEnumerable<TreeNode> FlattenTree(this TreeView tv)
    {
        return FlattenTree(tv.Nodes);
    }

    public static IEnumerable<TreeNode> FlattenTree(this TreeNodeCollection coll)
    {
        return coll.Cast<TreeNode>()
                    .Concat(coll.Cast<TreeNode>()
                                .SelectMany(x => FlattenTree(x.Nodes)));
    }
}

我找到了我得到这个的链接--它非常容易使用。看一看。Is there a method for searching for TreeNode.Text field in TreeView.Nodes collection?

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17630557

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档