C# 递归集合搜索
我有一个对象集合(C# 递归集合搜索,c#,search,recursion,task-parallel-library,icollection,C#,Search,Recursion,Task Parallel Library,Icollection,我有一个对象集合(列表),如下所述: class Element { string Name; string Value; ICollection<Element> ChildCollection; IDictionary<string, string> Attributes; } 目前,我正在使用递归搜索每个顶级(A、B、C)元素的属性字典,以查找特定的KeyValuePair。如果在顶级元素中找不到它,我将以相同的方式开始搜索它的子元素集合(1、1.
列表
),如下所述:
class Element
{
string Name;
string Value;
ICollection<Element> ChildCollection;
IDictionary<string, string> Attributes;
}
目前,我正在使用递归搜索每个顶级(A、B、C)元素的属性
字典
,以查找特定的KeyValuePair
。如果在顶级元素
中找不到它,我将以相同的方式开始搜索它的子元素
集合(1、1.1、2、2.1、n等)
我想知道的是,是否有更好的方法在这些对象上实现搜索,或者在这个例子中递归是更好的答案,我是否应该像现在一样实现搜索,top->child->child->等等,或者我是否应该以其他方式搜索,比如首先搜索所有顶级
我可以,并且使用TPL并行搜索每个顶层(A、B、C)是否合理?您可以重用专门为以不同方式遍历而设计的现有组件,例如。它允许您先了解深度或广度。它允许您遍历可枚举树,深度或宽度优先 获取扁平目录枚举的示例:
IEnumerable<DirectoryInfo> directories = ... ;
IEnumerable<DirectoryInfo> allDirsFlattened = directories.Traverse(TraverseKind.BreadthFirst, dir => dir.EnumerateDirectories());
foreach (DirectoryInfo directoryInfo in allDirsFlattened)
{
...
}
IEnumerable目录=;
IEnumerable allDirsFlattened=directories.Traverse(TraverseKind.BreadthFirst,dir=>dir.EnumerateDirectories());
foreach(所有目录中的DirectoryInfo DirectoryInfo已设置)
{
...
}
对于BreadhFirst,它在内部使用;对于DepthFirst,它在内部使用
它不是并行地遍历节点,除非遍历需要资源,否则在这个级别上使用并行是不合适的。但这取决于上下文。您可以重用专门为以不同方式进行遍历而设计的现有组件,例如。它允许您先了解深度或广度。它允许您遍历可枚举树,深度或宽度优先 获取扁平目录枚举的示例:
IEnumerable<DirectoryInfo> directories = ... ;
IEnumerable<DirectoryInfo> allDirsFlattened = directories.Traverse(TraverseKind.BreadthFirst, dir => dir.EnumerateDirectories());
foreach (DirectoryInfo directoryInfo in allDirsFlattened)
{
...
}
IEnumerable目录=;
IEnumerable allDirsFlattened=directories.Traverse(TraverseKind.BreadthFirst,dir=>dir.EnumerateDirectories());
foreach(所有目录中的DirectoryInfo DirectoryInfo已设置)
{
...
}
对于BreadhFirst,它在内部使用;对于DepthFirst,它在内部使用
它不是并行地遍历节点,除非遍历需要资源,否则在这个级别上使用并行是不合适的。但这取决于上下文。递归是实现树搜索的一种方法,在树搜索中,您可以按深度优先顺序访问元素。通过使用堆栈数据结构来存储需要访问的树节点,可以使用循环而不是递归来实现相同的算法 如果对队列而不是堆栈使用相同的算法,则搜索将以呼吸优先顺序进行 在这两种情况下,通用算法如下所示:
- 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)
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 ...) {
...
}
}
请注意,该算法不是递归的:它使用
节点的显式集合
来保存搜索的当前状态,而递归实现则使用调用堆栈来实现相同的目的。如果节点
是一个堆栈
,则搜索继续进行;如果节点
是一个队列
,则搜索将继续。递归是实现树搜索的一种方法,在树搜索中,您将按深度优先顺序访问元素。通过使用堆栈数据结构来存储需要访问的树节点,可以使用循环而不是递归来实现相同的算法
如果对队列而不是堆栈使用相同的算法,则搜索将以呼吸优先顺序进行
在这两种情况下,通用算法如下所示:
- 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)
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 ...) {
...
}
}
请注意,该算法不是递归的:它使用
节点的显式集合
来保存搜索的当前状态,而递归实现则使用调用堆栈来实现相同的目的。如果节点
是一个堆栈
,则搜索继续进行;如果节点
是一个队列
,搜索将继续进行。我从某个地方抓取了这个位,它不是我的,但我无法提供指向它的链接。这个类为递归搜索展平了一个树状视图,看起来它也应该为您做同样的事情
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)));
}
}
公共静态类SOExtension
{
公共静态IEnumerable树(此树视图电视)
{
返回扁平树(tv.Nodes);
}
公共静态IEnumerable Flattree(此TreeNodeCollection coll)
{
返回coll.Cast()
.Concat(coll.Cast)()
.SelectMany(x=>flattree(x.Nodes));
}
}
我找到了这个链接,它很容易使用。看一看 我从某处抓到了这一点,它不是我的,但我无法提供指向它的链接。这个类为递归搜索展平了一个树状视图,看起来它也应该为您做同样的事情
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)));
}
}
公共静态类SOExtension
{
公共静态IEnumerable树(此树视图电视)
{
返回扁平树(tv.Nodes);
}
公共静态IEnumerable Flattree(此TreeNodeCollection coll)
{
返回coll.Cast()
.Concat(coll.Cast)()
.SelectMany(x=>flattree(x.Nodes));
}
}
我找到了这个链接,它很容易使用。看一看 你在寻找什么?你在寻找什么?这让我朝着我希望的方向前进。答案也解释得很好,所以谢谢。这让我朝着我希望的方向前进。答案也解释得很好,谢谢。