恢复“父子关系”树的最有效方法是什么?

时间:2014-01-08 20:15:28

标签: c# algorithm

我有一个班级:

class DisplayableUnit
{
    public string ID; //unique ID which is not repeated
    public string ParentID; //ID of parent DisplayableUnit
    [NonSerialized]
    public DisplayableUnit ParentDU; //Instance of parent displayable unit

    //other fields
}

此课程的每个实例都存储在列表中。 在某些时候,我将每个实例序列化为一个单独的文件,然后将其加载回来。 ParentDU 字段当然会变成 null ,我真的不需要序列化它。

现在我的任务是恢复实例之间的关系,所以我寻找一种最清晰,最快捷的方法。

我拥有的是包含所有反序列化对象的**List<DisplayableUnit> LoadedProject.DUnits**

我写了一些功能来做到这一点,但使用它们仍然有点奇怪和耗时。

private static List<DisplayableUnit> GetChildDisplayableUnitsFor(DisplayableUnit dunit)
{
    List<DisplayableUnit> ret_list = new List<DisplayableUnit>();

    for (int i = 0; i < LoadedProject.DUnits.Count; i++) //iterate through all deserialized units
        if (string.Compare(LoadedProject.DUnits[i].ParentDUnitID, dunit.ID) == 0) //compare the own ID and parentID of potential child
            ret_list.Add(LoadedProject.DUnits[i]); //add to list if this is child

    return ret_list;
}

public static void RestoreTreeForDU(DisplayableUnit du)
{
    List<DisplayableUnit> childs = GetChildDisplayableUnitsFor(du); //get childs units

    for (int i = 0; i < childs.Count; i++) //iterate through those
    {
        childs[i].ParentDUnit = du; //restore instance link
        RestoreTreeForDU(childs[i]); //make just found child as parent and see if we can restore childs for it.
    }
}

public static List<DisplayableUnit> GetParentDUnits()
{
    List<DisplayableUnit> ret_list = new List<DisplayableUnit>();

    for (int i = 0; i < LoadedProject.DUnits.Count; i++)
        if (string.IsNullOrEmpty(LoadedProject.DUnits[i].ParentDUnitID))
            ret_list.Add(LoadedProject.DUnits[i]);

    return ret_list;
}

这就是我开始思考接下来要做什么的事情......我最初需要做些什么才能恢复关系? 我是否只需要遍历 LoadedProject.DUnits (所有反序列化的单元)并为每个单元调用RestoreTreeForDU?

这看起来很奇怪,因为那里的一些单位已经恢复等等。 这一切都让人感到困惑:/

1 个答案:

答案 0 :(得分:2)

创建对实际对象的ID查找,然后您可以简单地遍历列表并从该查找中获取其父级的值:

List<DisplayableUnit> list = new List<DisplayableUnit>();
//todo deserialize into list

var lookup = list.ToDictionary(unit => unit.ID, unit => unit);
foreach (var unit in list)
    unit.ParentDU = lookup[unit.ParentID];