[英]Generic Tree Structure - How to populate an org chart
我有一个相当琐碎的问题,但我想确保在.Net 4.5中以最“优雅”的方式做到这一点,并且我希望有比我聪明的人提出一些意见。
我有一个代表这样的通用树结构的类:
public class TreeNode<T>
{
List<TreeNode<T>> Children;
T Item {get;set;}
public TreeNode (T item)
{
Item = item;
}
public TreeNode<T> AddChild(T item)
{
TreeNode<T> nodeItem = new TreeNode<T>(item);
Children.Add(nodeItem);
return nodeItem;
}
}
现在,我有一个Person类,代表该组织的一名员工。 每个Person
对象都有一个ID
和一个BossID
指向其上级。
多个员工可以拥有同一位老板,因此为什么我要尝试使用这种树形结构创建组织结构图。
顶部节点将是BossID
为null的Person
对象(这是一个int?
)。 我可以很快使用LINQ。
下一步让我有些困惑。 有多种方法,但对我来说似乎有些草率,我知道必须有一种更轻松/优雅的方法来填写组织结构图的其余部分。
因此,现在我有了一个List<Person>
的通用对象,该对象持有所有雇员,以及他们的各种BossID
和可以添加子节点的这种通用树结构。
这都是非常基本的,但是填充树的正确顺序是什么? 我是否应该递归迭代? 我知道这里涉及回溯,这就是我陷入困境的地方。
我很抱歉,我的背景不是计算机科学专业,如果我意识到树结构,链表以及其他所有内容都是微不足道的。 但这是我的第一次尝试,我想看看它是如何正确完成的。
我感谢任何指导。
因此,假设您定义了一个Person
类:
public class Person
{
public int ID;
public int? BossID;
}
...并且您将List<Person>
定义为people
则此方法有效:
var lookup = people.ToLookup(p => p.BossID);
Action<TreeNode<Person>> addChildren = null;
addChildren = p =>
{
foreach (var child in lookup[p.Item.ID])
{
var childNode = p.AddChild(child);
addChildren(childNode);
}
};
var trees =
from boss in lookup[null]
select new TreeNode<Person>(boss);
foreach (var tree in trees)
{
addChildren(tree);
}
这是假设你可能有不止一个人用null
的老板。 如果不行,请运行此代码并执行trees.First()
。
我使用的TreeNode<T>
的定义是这样的:
public class TreeNode<T>
{
private List<TreeNode<T>> Children;
public T Item { get; set; }
public TreeNode(T item)
{
this.Item = item;
this.Children = new List<TreeNode<T>>();
}
public TreeNode<T> AddChild(T item)
{
var nodeItem = new TreeNode<T>(item);
this.Children.Add(nodeItem);
return nodeItem;
}
}
您可以将TreeNode<T>
缩短为:
public class TreeNode<T> : List<TreeNode<T>>
{
public T Item { get; set; }
public TreeNode(T item)
{
this.Item = item;
}
}
...然后您需要将addChildren
修改为:
Action<TreeNode<Person>> addChildren = null;
addChildren = p =>
{
foreach (var child in lookup[p.Item.ID])
{
var childNode = new TreeNode<Person>(child);
p.Add(childNode);
addChildren(childNode);
}
};
...但是您将拥有所有可用于TreeNode<T>
的标准List<>
运算符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.