繁体   English   中英

通用树结构-如何填充组织结构图

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM