簡體   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