在c#中遍历对象树

Posted

技术标签:

【中文标题】在c#中遍历对象树【英文标题】:Traversing a tree of objects in c# 【发布时间】:2009-01-14 16:36:32 【问题描述】:

我有一棵由多个对象组成的树,其中每个对象都有一个名称 (string)、id (int) 以及可能具有相同类型的一组子对象。如何遍历整个树并打印出所有的 ID 和名称?

我是编程新手,坦率地说,我很难理解这一点,因为我不知道有多少级别。现在我正在使用foreach 循环来获取根目录下的父对象,但这意味着我无法获取子对象。

【问题讨论】:

我同意。使用递归保持简单。 【参考方案1】:

使用递归的算法是这样的:

printNode(Node node)

  printTitle(node.title)
  foreach (Node child in node.children)
  
    printNode(child); //<-- recursive
  

这是一个版本,它还跟踪递归的嵌套深度(即我们是否打印根的孩子、孙子、曾孙等):

printRoot(Node node)

  printNode(node, 0);


printNode(Node node, int level)

  printTitle(node.title)
  foreach (Node child in node.children)
  
    printNode(child, level + 1); //<-- recursive
  

【讨论】:

【参考方案2】:

嗯,你总是可以使用递归,但在“现实世界”的编程场景中,如果你不跟踪深度,它可能会导致坏事。

这是一个用于二叉树的示例:http://www.codeproject.com/KB/recipes/BinarySearchTree.aspx

如果您不熟悉整个数据结构,我会搜索链接列表和其他树结构。有很多知识需要掌握。

【讨论】:

您能说明使用递归的替代方法吗(即我的示例伪代码的非递归版本)? 我认为它会有点大而且笨重。你的例子对他来说绝对是最简单、最容易掌握的。我只是想强调递归在生产环境中通常是一个坏主意。 如果您进行适当的检查以确保它永远不会无限递归,为什么这是一个坏主意?我们在生产环境中的几个地方使用递归,但限制了它的递归级别。 您需要以某种方式跟踪上下文:因此,如果您不打算递归(将上下文保留在程序堆栈上),那么您需要将其保留在堆上(也许通过使用Stack) 类型的局部变量?我不知道你为什么说这“通常是个坏主意”,假设任何深度很深的树? 如果你像汤姆安德森提到的那样实现它,通过跟踪深度并限制它,那么它就没有真正的问题。但是对于一个新程序员来说,很容易陷入堆栈溢出的情况。

以上是关于在c#中遍历对象树的主要内容,如果未能解决你的问题,请参考以下文章

在c#中遍历通用类型列表

C#:循环遍历嵌套结构的成员对象

C#遍历对象属性

通过 ASP.NET MVC 在 C# 视图中遍历匿名对象的嵌套 LINQ 查询

组合模式(遍历树)

Unity 遍历敌人——使用四叉树空间分区