KP.*_*KP. 0 c# asp.net queue recursion breadth-first-search
我正在尝试编写一个扩展方法,System.Web.UI.Control为其搜索ControlCollection特定的实例Type,并返回找到的第一个实例.深度优先很简单,但我想首先搜索广度,以便更高的集合优先.
我当前的方法存在缺陷并将提前退出,在整个搜索未完成的某些情况下返回null.我希望我接近正确的解决方案,但需要一些新的眼睛.有什么建议?
public static T FindFirstControlOfType<T>(this Control rootControl, bool searchRecursively) where T : Control
{
// list for container controls
List<Control> controlsWithChildren = new List<Control>();
// iterate the current control collection first
foreach (Control child in rootControl.Controls)
{
if (child.GetType().IsAssignableFrom(typeof(T)))
{
return (T)child;
}
// track those controls containing children
if (child.HasControls())
{
controlsWithChildren.Add(child);
}
}
// if recursion is enabled, search the child nodes
if (searchRecursively)
{
foreach (Control control in controlsWithChildren)
{
return FindFirstControlOfType<T>(control, true);
}
}
// if never found, return null
return null;
}
Run Code Online (Sandbox Code Playgroud)
编辑 - 基于明确答案的工作解决方案,对任何感兴趣的人:
public static T FindFirstControlOfType<T>(this Control rootControl, bool searchNestedControls) where T : Control
{
Queue<Control> queue = new Queue<Control>();
EnqueueChildControls(queue, rootControl);
while (queue.Count > 0)
{
Control current = queue.Dequeue();
if (current.GetType() == typeof(T))
{
return (T)current;
}
if (searchNestedControls)
{
EnqueueChildControls(queue, current);
}
}
return null;
}
private static void EnqueueChildControls(Queue<Control> queue, Control control)
{
foreach (Control current in control.Controls)
{
queue.Enqueue(current);
}
}
Run Code Online (Sandbox Code Playgroud)
广度优先搜索(伪代码)
Queue fringe
fringe.Enqueue(rootControl)
while(fringe.Count > 0)
{
current = fringe.Dequeue()
Visit(current)
fringe.EnqueueAll(current.Children)
}
Run Code Online (Sandbox Code Playgroud)
广度优先搜索不需要递归.
Visit是你想用当前对象做什么的.如果你正在寻找某些东西那么Visit意味着:if(current matches criteria) return current
更新:工作示例:https://gist.github.com/1960108
| 归档时间: |
|
| 查看次数: |
1068 次 |
| 最近记录: |