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

本文关键字:叶节点 遍历 | 更新日期: 2023-09-27 18:37:01

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

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());
    }
}

一个节点可以有任意数量的子节点。这是我写的打印所有叶节点的内容。我什么也得不到,我认为只有最后一行 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("");
    }

感谢您的任何帮助。树类是这个,实际上我在任何地方都找不到我的调试窗口......我只写了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();
    }
}

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

您需要替换此行

if (currentNode.Children == null)

有了这个

if (currentNode.Children.Count == 0)

这将检查列表是否没有元素(没有子元素)。由于您始终初始化列表,因此即使列表为空,它也不会一开始为 null。

通用解决方案:

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);

单独的节点遍历和遍历操作,如下所示:

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

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 + " ");
    }       
}