如何遍历C#中的多层次数组

时间:2011-05-27 20:37:30

标签: c#

假设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){...}

6 个答案:

答案 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
}

两种方法都使用递归,因此它们可能会在非常深的结构上失败。