遍历树 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();
}
}
您需要替换此行
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 + " ");
}
}