C#树/集合算法
我需要用一些项(当然是在parent-child1-child2-…childN关系中)填充树状UI控件,在继续之前,我希望确保保存内容的my collection的顺序正确,如下所示: 我的集合(未排序的ObservableCollection)中的每个对象(在本例中是我的Category类的实例)都有一个公共属性(ParentCategoryID作为字符串),该属性指向另一个“Category”,该“Category”将是我树中的父对象。树中的节点可以有0个或任意数量的子节点 因此,在填充树时,要显示的每个“类别”对象在集合中已经有其“父类别”(基于ParentCategoryID)C#树/集合算法,c#,algorithm,tree,collections,C#,Algorithm,Tree,Collections,我需要用一些项(当然是在parent-child1-child2-…childN关系中)填充树状UI控件,在继续之前,我希望确保保存内容的my collection的顺序正确,如下所示: 我的集合(未排序的ObservableCollection)中的每个对象(在本例中是我的Category类的实例)都有一个公共属性(ParentCategoryID作为字符串),该属性指向另一个“Category”,该“Category”将是我树中的父对象。树中的节点可以有0个或任意数量的子节点 因此,在填充树
在将元素添加到树中之前,我应该使用什么算法来确保我的集合是按这种方式排序的?也许子节点不应该知道它的父节点,在我看来,它应该相反。当每个父节点持有子节点的集合,并且可以在添加新节点后对该集合进行排序时。也许这能解决你的问题
问候。我不确定这是否是您想要的,但希望它能帮助您:
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
}
使用系统;
使用System.Linq;
使用系统集合;
使用System.Collections.Generic;
公共课程
{
公共静态void Main(字符串[]args)
{
/*树形结构
A.
D
E
B
F
我
J
C
G
H
*/
var a=新类别(“a”,空);
var b=新类别(“b”,空);
var c=新类别(“c”,空);
var d=新类别(“d”、“a”);
var e=新类别(“e”、“d”);
var f=新类别(“f”、“b”);
var g=新类别(“g”、“c”);
var h=新类别(“h”、“g”);
var i=新类别(“i”、“b”);
var j=新类别(“j”、“i”);
var k=新类别(“k”、“z”);
var list=新类别集合{k,j,i,h,g,f,e,d,c,b,a};
foreach(list.SortForTree()中的变量类别)
{
WriteLine(“名称:{0};父项:{1}”,category.Name,category.ParentCategoryID);
}
}
}
类别
{
公共字符串ParentCategoryID{get;set;}
公共字符串名称{get;set;}
公共类别(字符串名称、字符串parentCategoryID)
{
名称=名称;
ParentCategoryID=ParentCategoryID;
}
}
类类别集合:IEnumerable
{
私有列表=新列表();
公共无效添加(类别)
{
列表。添加(类别);
}
公共IEnumerable排序树()
{
var target=newdictionary();
SortForTree(列表、目标);
返回目标值;
}
私有void排序树(列表源、字典目标)
{
var temp=新列表();
foreach(源中的var c)
{
if(c.ParentCategoryID==null | |(target.ContainsKey(c.ParentCategoryID)&&!target.ContainsKey(c.Name)))
{
target.Add(c.Name,c);
}
其他的
{
if(source.Exists(o=>o.Name==c.ParentCategoryID))
{
温度添加(c);
}
}
}
如果(温度计数>0)排序树(温度,目标);
}
#区域可数成员
公共IEnumerator GetEnumerator()
{
返回list.GetEnumerator();
}
#端区
#区域可数成员
IEnumerator IEnumerable.GetEnumerator()
{
返回list.GetEnumerator();
}
#端区
}
谢谢您的帮助。它似乎工作正常,除非将类别的父级设置为不存在的父级。在本例中,它抛出StackOverflow异常。我在SortForTree的foreach循环(在else分支中)中使用了此代码:如果(source.Find(delegate(Category o){return o.Name==c.ParentCategoryID;})!=null){temp.Add(c);}否则继续?抢手货有趣的是,我在StackOverflow上发布了导致StackOverflow的代码!我更新了代码,以稍微不同的方式合并了您的修复。