如何实现GetAllNodes方法以按级别顺序返回所有节点的集合?

时间:2013-09-17 09:12:15

标签: c# algorithm

public class TreeNode<T>
{
  private List<TreeNode<T>> _children = new List<TreeNode<T>>();
  public T Data { get; set; }
  public TreeNode<T> Parent { get; private set; }
  public ReadOnlyCollection<TreeNode<T>> Children {
    get {
      return new ReadOnlyCollection<TreeNode<T>>(_children);
    }
  }
  public void AddChild(TreeNode<T> child)
  {
    _children.Add(child);
  }
  public ICollection<TreeNode<T>> GetAllNodes()
  {
    throw new NotImplementedException();
  }
}

1 个答案:

答案 0 :(得分:3)

这种遍历称为Breadth-First Traversal

public ICollection<TreeNode<T>> GetAllNodes()
{
    var allNodes = new List<TreeNode<T>>();
    var queue = new Queue<TreeNode<T>>();
    queue.Enqueue(this); // will include root node

    while (queue.Any())
    {
        var current = queue.Dequeue();
        allNodes.Add(current);
        foreach (var child in current._children)
            queue.Enqueue(child);
    }

    return allNodes;
}

工作原理:考虑以下树

enter image description here

让我们看一下[方括号]将包含哪些队列以及将添加到结果中的内容(括号):

之前循环:

  • root已添加到队列:[N0]

第一循环:

  • 从队列中删除第一项:
  • 第一项添加到结果中:(N0)
  • N0的所有子项都已添加到队列中:[N1-1][N1-2]

第二次循环:

  • 从队列中删除了第一项N1-1[N1-2]
  • 第一项添加到结果中:(N0)(N1-1)
  • N1-1的所有子项都已添加到队列中:[N1-2][N2-1]

第三循环:

  • 从队列中删除了第一项N1-2[N2-1]
  • 第一项添加到结果中:(N0)(N1-1)(N1-2)
  • N1-2的所有子项都已添加到队列中:[N2-1][N2-2][N2-3]

第四循环:

  • 从队列中删除了第一项N2-1[N2-2][N2-3]
  • 第一项添加到结果中:(N0)(N1-1)(N1-2)(N2-1)
  • N2-1的所有子项都已添加到队列中:[N2-2][N2-3][N3-1]

所有这些项目都没有子项,因此进一步的循环只会从队列中逐个删除它们并添加到结果中。