2016-03-22 31 views
0

私はかなり些細な問題があるはずですが、私はこれを.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オブジェクトは、その上位を指しているIDBossIDを持ちます。

複数の従業員が同じボスを持つことができます。なぜこのツリー構造の組織図を作成しようとしていますか。

先頭ノードは、BossIDがヌル(int?)のPersonオブジェクトになります。私はすぐにLINQを手に入れることができます。

これは私に少し困惑している次のステップです。複数のアプローチがありますが、どちらかというと私には少しばかり見えますが、残りの組織図を記入するのははるかに簡単でエレガントな方法でなければなりません。

今私はList<Person>という一般的なオブジェクトを持っていて、さまざまなBossIDと子ノードを追加できる汎用ツリー構造を持っています。

これはすべて非常に基本的ですが、ツリーを埋める正しい順序は何ですか?私は再帰的に行を反復することになっていますか?ここにはバックトラックが含まれていることがわかります。ここで私は困惑しています。

私はお詫びします、私の背景はコンピュータサイエンスではありません、そして、私はそれが木構造、リンクされたリスト、および他のすべてが些細なものであることを認識していました。しかしこれは私の最初の試みであり、どのように正しく行われているかを見たいと思っています。

どのようなガイダンスもありがとうございます。

public class Person 
{ 
    public int ID; 
    public int? BossID; 
} 

...そしてあなたがpeopleとして定義されList<Person>を持っている、これは動作します:

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); 
} 

これは、あなたがかもしれないことを前提としていますが、このように定義Personクラスを持って与えられたので、

+0

だから、基本的にあなたの質問は、あなたが人のリストを持っていると仮定して、orgツリーを作成することですか? –

+0

それはそれほど簡単です。私はその汎用ツリークラスを持っています。自分のIDとBossのIDを持つPeopleオブジェクトのList <>を持っています。私はちょうど4.5の下で最もクリーンなアプローチが何であるかを知りたい。私は木を埋める方法を調べることができますが、そこには非常に貧弱な例がいくつかあり、入力を探しています。 LINQのようなものでは、私のためのコードが大幅に簡素化されています。 – Patrick

答えて

2

、 1人以上の人に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; 
    } 
} 

public class TreeNode<T> : List<TreeNode<T>> 
{ 
    public T Item { get; set; } 

    public TreeNode(T item) 
    { 
     this.Item = item; 
    } 
} 

...そしてこれにaddChildrenを修正するあなたの必要性:

私が使用しTreeNode<T>の定義は、このでした

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); 
    } 
}; 

...しかし、あなたはすべてのスタンドを持っていますrd List<>オペレーターはTreeNode<T>で利用可能です。

+0

@パトリック - 上司が1人しかいないことが分かっているなら、 'var boss = trees.First();'を実行してください。 – Enigmativity

+0

1つのボスしか存在しない場合は、Single/SingleOrDefaultを使用すると、1つのボスしか許可されないため、データのエラーが存在するかどうかを知ることができます。 –

+0

@Enigmativity私は、単一のパラメータ、すべての人々( 'List people')。 'people.Count'は開始時に25に等しくなります。期待通りに動作しません。 'foreach(ツリー内のvarツリー)'という行は 'addChildren(tree);' tree.Count = 0'を呼び出してループに入ります。私は問題が何であるか正確にはわからない。 – Patrick

関連する問題