使用对象列表构建树

时间:2010-03-04 10:12:35

标签: c# algorithm language-agnostic

我有一个具有属性id和parent_id的对象列表 我想建一棵树来连接那些孩子和父母 1父母可能有几个孩子,并且有一个对象将成为所有对象的祖先。

实施该算法的最快算法是什么? 我使用C#作为编程语言,但其他语言也没问题。

3 个答案:

答案 0 :(得分:4)

这样的事情可以解决问题:

public List<Node> MakeTreeFromFlatList(IEnumerable<Node> flatList)
{
    var dic = flatList.ToDictionary(n => n.Id, n => n);
    var rootNodes = new List<Node>();
    foreach(var node in flatList)
    {
        if (node.ParentId.HasValue)
        {
            Node parent = dic[node.ParentId.Value];
            node.Parent = parent;
            parent.Children.Add(node);
        }
        else
        {
            rootNodes.Add(node);
        }
    }
    return rootNodes;
}

(假设ParentId是Nullable<int>,并且对于根节点为空)

答案 1 :(得分:3)

你可以使用字典:

var dict = new Dictionary<Id, Node>();

foreach (var item in items)
{
    dict[item.Id] = new Node(item);
}

foreach (var item in items)
{
    dict[item.ParentId].AddChild(dict[item.Id]);
}

答案 2 :(得分:1)

我更喜欢这种结构。通过维护单个列表(您可能希望使用字典或类似的速度)并将其传递到GetChildItems函数,您可以更灵活,更容易排序,添加,删除,保存到数据库等。

在将列表呈现给视图时,您只需要GetChildItem函数,并且您希望树结构可以像您所说的那样轻松编辑。在这种情况下,您可以拥有一个包含完整列表的视图模型以及传递到每个项目视图中的项目

public class Item
{
    public string Id { get; set; }
    public string ParentId { get; set; }

    public IEnumerable<Item> GetChildItems(List<Item> allItems)
    {
        return allItems.Where(i => i.Id == this.ParentId);
    }
}

public class Tree
{
    public List<Item> Items { get; set; }

    public IEnumerable<Item> RootItems(List<Item> allItems)
    {
        return allItems.Where(i => i.ParentId == null);
    }
}

注意:上面的类结构旨在模仿传统的复杂对象模式。这些天你可能只是在视图模型中有GetChildItems(List allItems,Item parentItem)