假设rootNode是一个多层次的数据结构。
rootNode.Add(node1);
rootNode.Add(node2);
node1.Add(node3);
node1.Add(node4);
node3.Add(node5);
如果使用foreach遍历rootNode将只获取node1,node2。如何遍历rootNode中的所有节点?
foreach(var node in rootNode){...}
答案 0 :(得分:2)
您可以使用recursion遍历树。
VisitNode(Node n){
foreach(var cn in n.Children){
VisitNode(cn);
}
//Do what you want to do with your node here
Console.Writeline(n.Value);
}
Here is an example广度优先遍历。
答案 1 :(得分:1)
进行递归通话:
TraverseNodes(parentNode)
{
for each (Node node in parentNode)
{
if (node.Nodes.Count>0)
TraverseNodes(node);
}
}
答案 2 :(得分:1)
您可以设置一个简单的递归函数
//Pseudo-code
public void traverse(Node n)
{
if(n hasChildren)
{
foreach(Node child in n.children)
{
traverse(child);
}
}
}
答案 3 :(得分:1)
最简单的方法是递归。什么是递归? See this answer举个例子。
public void TraverseNodes(Node parentNode)
{
//iterate through child nodes
foreach(var node in parentNode)
{
//action
//iterate though child's child nodes.
TraverseNodes(node);
}
}
基本上,您通过在所有父项(从第一个父项开始)上调用相同的方法(TraverseNodes)对所有子项执行相同的操作。
答案 4 :(得分:1)
如果您的结构不太深,那么您可以安全地使用其他答案中给出的递归方法。
但是,如果您的结构可能非常深,那么使用递归运行会导致调用堆栈并导致StackOverflowException
的风险。
以下是遍历结构的非递归方式的示例:
var stack = new Stack<TNode>();
stack.Push(rootNode);
while (stack.Count > 0)
{
var node = stack.Pop();
// do whatever you need to do with each node here
foreach (var childNode in node)
{
stack.Push(childNode);
}
}
答案 5 :(得分:1)
即使已经发布了(工作)递归方法,我还想提供两种方法。
第一个“将”树中的每个节点“推送”到可以“消耗”它的Action<Node>
。
public void TraverseWithAction(Action<Node> nodeAction) {
nodeAction(this);
foreach(Node n in this.children) {
n.TraverseWithAction(nodeAction);
}
}
用法示例:
rootNode.TraverseWithAction(n => buffer.Append(n.ToString()));
第二个递归地在根节点及其所有子节点上提供IEnumerable<Node>
。 (并且,是的,只有两个循环,但它们可以处理比两个更深的树。)
public IEnumerable<Node> TraverseAsEnumerable() {
yield return this;
foreach(Node n in this.children) {
foreach (Node n2 in n.TraverseAsEnumerable()) {
yield return n2;
}
}
}
用法示例:
foreach (Node n in rootNode.TraverseAsEnumerable()) {
// do something with n
}
两种方法都使用递归,因此它们可能会在非常深的结构上失败。