2009-05-16 7 views
2

일부 항목 (물론 parent-child1-child2 -... childN 관계)에 트리 모양의 UI 컨트롤을 채워야하고 진행하기 전에 보유하고있는 컬렉션C# tree/collection algorithm

내 컬렉션 (순서가 지정되지 않은 ObservableCollection)의 각 개체 (이 경우에는 내 Category 클래스의 인스턴스)에 다른 개체를 가리키는 public 속성 (문자열로 ParentCategoryID)이 있습니다. 카테고리 '는 내 나무의 부모가 될 것입니다. 트리의 노드는 0 또는 임의의 수의 자식을 가질 수 있습니다.

트리를 채울 때 표시 될 각 '범주'개체에는 컬렉션의 ParentCategoryID를 기준으로 이미 '부모 범주'가 있습니다.

트리의 요소를 추가하기 전에 내 컬렉션이 이러한 방식으로 정렬되도록하려면 어떤 알고리즘을 사용해야합니까?

답변

2

는 잘 모르겠어요하지만 희망이 도움이됩니다 이것에 대한

using System; 
using System.Linq; 
using System.Collections; 
using System.Collections.Generic; 
public class Program 
{ 
    public static void Main(string[] args) 
    { 
     /* Tree Structure 

     a 
      d 
      e 
     b 
      f 
      i 
      j 
     c 
      g 
      h 
     */ 

     var a = new Category("a", null); 
     var b = new Category("b", null); 
     var c = new Category("c", null); 
     var d = new Category("d", "a"); 
     var e = new Category("e", "d"); 
     var f = new Category("f", "b"); 
     var g = new Category("g", "c"); 
     var h = new Category("h", "g"); 
     var i = new Category("i", "b"); 
     var j = new Category("j", "i"); 
     var k = new Category("k", "z"); 

     var list = new CategoryCollection { k, j, i, h, g, f, e, d, c, b, a }; 
     foreach (var category in list.SortForTree()) 
     { 
     Console.WriteLine("Name: {0}; Parent: {1}", category.Name, category.ParentCategoryID); 
     } 
    } 
} 

class Category 
{ 
    public string ParentCategoryID { get; set; } 
    public string Name { get; set; } 
    public Category(string name, string parentCategoryID) 
    { 
     Name = name; 
     ParentCategoryID = parentCategoryID; 
    } 
} 

class CategoryCollection : IEnumerable<Category> 
{ 
    private List<Category> list = new List<Category>(); 

    public void Add(Category category) 
    { 
     list.Add(category); 
    } 

    public IEnumerable<Category> SortForTree() 
    { 
     var target = new Dictionary<string, Category>(); 

     SortForTree(list, target); 

     return target.Values; 
    } 

    private void SortForTree(List<Category> source, Dictionary<string, Category> target) 
    { 
     var temp = new List<Category>(); 

     foreach (var c in source) 
     { 
     if (c.ParentCategoryID == null || (target.ContainsKey(c.ParentCategoryID) && !target.ContainsKey(c.Name))) 
     { 
      target.Add(c.Name, c); 
     } 
     else 
     { 
      if (source.Exists(o => o.Name == c.ParentCategoryID)) 
      { 
       temp.Add(c); 
      } 
     } 
     } 

     if (temp.Count > 0) SortForTree(temp, target); 
    } 

    #region IEnumerable<Category> Members 

    public IEnumerator<Category> GetEnumerator() 
    { 
     return list.GetEnumerator(); 
    } 

    #endregion 

    #region IEnumerable Members 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return list.GetEnumerator(); 
    } 

    #endregion 
} 
+1

감사합니다. 카테고리의 부모를 존재하지 않는 카테고리로 설정하는 경우를 제외하고는 정상적으로 작동하는 것 같습니다. 이 경우 StackOverflow 예외가 발생합니다. SortForTree의 foreach 루프에서이 코드를 사용했습니다 (다른 brach에서는). : if (source.Find (delegate (Category o) {return o.Name == c.ParentCategoryID;})! = null) {temp.Add (c); } else continue ...? –

+0

잘자요. StackOverflow를 발생시키는 StackOverflow에 코드를 게시 한 것은 재미있었습니다. 수정 사항을 약간 다른 방식으로 통합하도록 코드를 업데이트했습니다. – Robin

0

어쩌면 childnode는 부모 노드를 알지 못합니다. 제 생각에는 반대가되어야합니다. 각 부모 노드가 자식 노드의 컬렉션을 보유하고이 컬렉션을 새 노드를 추가 한 후에 정렬 할 수 있습니다. 아마도 이것은 당신의 문제를 해결할 것입니다.

감사합니다. 이 당신을 위해 무엇을 찾고있는 경우

관련 문제