遍历树C#中的所有叶节点

traverse all leaf nodes in a tree C#

我正在尝试使用队列遍历树中的所有叶节点。 但我无法获得任何输出。

class MyNode<T>
{
    public T Data { get; set; }
    public MyNode<T> Parent { get; set; }
    public List<MyNode<T>> Children = new List<MyNode<T>>();
    public MyNode(T data, MyNode<T> parent)
    {
        Data = data;
        Parent = parent;
    }

    public override string ToString()
    {
        if (Children == null) return Data.ToString();
        return string.Format("{0} {1} ", Data.ToString(), Children.ToString());
    }

}

一个节点可以有任意数量的children。这是我写的打印所有叶节点的内容。我什么也得不到,我想只有最后一行 Console.WriteLine("");被处决了,但我不明白为什么。

    public static void PrintSentence(MyNode<string> root)
    {
        if (root == null)   // Return when the tree is empty.
            return;

        Queue<MyNode<string>> nodeQueue = new Queue<MyNode<string>>();
        nodeQueue.Enqueue(root);

        MyNode<string> currentNode = root;

        while (nodeQueue.Count != 0)
        {
            currentNode = nodeQueue.Peek();
            nodeQueue.Dequeue();

            if (currentNode.Children == null)   // Print strings only when the current node is a leaf node.
                Console.Write(currentNode.Data + " ");

            for (int i = 0; i < currentNode.Children.Count(); i++)
                nodeQueue.Enqueue(currentNode.Children[i]);
        }

        Console.WriteLine("");

    }

感谢您的帮助。 树 class 就是这个,实际上我在任何地方都找不到我的调试 window ... 我只写了PrintSentence这个方法,其他的都是别人写的

class Tree<T>
{
    public MyNode<T> Root { get; set; }
    public Tree(MyNode<T> root) { Root = root; }
    public override string ToString()
    {
        if (Root == null) return "";
        return Root.ToString();
    }
}

您需要替换此行

if (currentNode.Children == null)

有了这个

if (currentNode.Children.Count == 0)

这将检查列表是否没有元素(没有子项)。因为你总是初始化你的列表,所以它一开始就不会是空的,即使它是空的。

像这样分离节点遍历和遍历动作:

我选择了递归,因为树的递归深度通常不是问题,而且队列不需要太多内存。

public static class MyNodeExt<T>
{
   IEnumerable<T> TraverseLeafs<T>(this MyNode<T> node)
   {
       if (node.Children.Count == 0)
           yield return node;
       else
       {
           foreach(var child in root.Children)
           {
               foreach(var subchild in child.TraverseLeafs())
               {
                   yield return subchild;
               }
           } 
       }
   }
}

并单独遍历动作:

public static void PrintSentence(MyNode<string> root)
{
    foreach(var node in root.TraverseLeafs())
    {
        Console.Write(node .Data + " ");
    }       
}

通用解决方案:

public static class Hierarchy
{
    /// <summary>
    /// Gets the collection of leafs (items that have no children) from a hierarchical collection
    /// </summary>
    /// <typeparam name="T">The collection type</typeparam>
    /// <param name="source">The sourceitem of the collection</param>
    /// <param name="getChildren">A method that returns the children of an item</param>
    /// <returns>The collection of leafs</returns>
    public static IEnumerable<T> GetLeafs<T>(T source, Func<T, IEnumerable<T>> getChildren)
    {
        if (!getChildren(source).Any())
        {
            yield return source;
        }
        else
        {
            foreach (var child in getChildren(source))
            {
                foreach (var subchild in GetLeafs(child, getChildren))
                {
                    yield return subchild;
                }
            }
        }
    }
}

用法:

    var leafs = Hierarchy.GetLeafs(root, (element) => element.Children);