【发布时间】:2018-02-22 15:18:38
【问题描述】:
目前,我有一个 Item 类和一个表示从 SQL Server 2012 DB 查询中检索到的平面数据的项目列表。这是 Item 类。
public class Item
{
public string Parent { get; set; }
public string Child { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
}
我需要将这些平面数据转换为树结构,并且能够在执行某些操作时遍历树。这是一些数据的视觉效果。我的树总是有一个根节点。
我在 SO 上看到了几篇与此相关的帖子,但我仍在为此苦苦挣扎。这是我拥有的通用 TreeNode 类。
public class TreeNode<T>
{
private readonly T _value;
private readonly List<TreeNode<T>> _children = new List<TreeNode<T>>();
public TreeNode(T value)
{
_value = value;
}
public TreeNode<T> this[int i]
{
get { return _children[i]; }
}
public TreeNode<T> Parent { get; private set; }
public T Value { get { return _value; } }
public ReadOnlyCollection<TreeNode<T>> Children
{
get { return _children.AsReadOnly(); }
}
public TreeNode<T> AddChild(T value)
{
var node = new TreeNode<T>(value) { Parent = this };
_children.Add(node);
return node;
}
public TreeNode<T>[] AddChildren(params T[] values)
{
return values.Select(AddChild).ToArray();
}
public bool RemoveChild(TreeNode<T> node)
{
return _children.Remove(node);
}
public void Traverse(Action<T> action)
{
action(Value);
foreach (var child in _children)
child.Traverse(action);
}
public IEnumerable<T> Flatten()
{
return new[] { Value }.Concat(_children.SelectMany(x => x.Flatten()));
}
}
我无法将平面数据递归加载到树结构中。我也不明白如何利用 Traverse 方法中的 Action 在遍历时执行某些任务。要填充树,我相信我需要从根开始。我是这样获得的:
var root = new TreeNode<Item>(items.Single(i => i.Parent == null));
然后我可以像这样加载第一级:
root.AddChildren(items.Where(i => i.Parent.Equals(root.Value.Child)).ToArray());
我的两个问题如下:
- 如何递归加载所有内容?
- 如何使用 Traverse 方法中的 Action 来简单地按项目名称和适当的缩进写出树结构(或执行任何任务)?
提前致谢!!
【问题讨论】:
-
每个帖子一个问题,拜托。如果有人答对了第一个问题,第二个答错了,另一个人答对了第一个问题,但第二个答对了,你会如何选择接受哪个答案?
-
我会将您的类的名称从 Item 更改为 Node,这是通常使用的。您的节点定义了错误的子节点: public string Child { get;放; }。它应该是 public List
Child { get;放; } 或者在二叉树的情况下有 public Node Left { get;放; } 和公共节点右 {get;放; } -
@jdweng - 不,Item 实际上代表我们 SQL 数据库的物料清单表中的一部分,并且该类不能更改。有一个递归 CTE,它会吐出代表 BOM 的平面项目列表。我需要将项目的平面列表转换为 TreeNodes 的 IEnumberable。列表中的平面项没有子项的集合。我正在尝试将平面项目映射到具有子节点(和父节点)的节点。谢谢。
标签: c# recursion tree parent-child treenode