从存储数据构建链表的最有效方法?

时间:2013-01-08 10:57:27

标签: c# xml algorithm data-structures linked-list

我将数据存储在描述链接列表的XML文档中;除了一个节点之外的所有节点都跟随另一个节点,因此数据看起来像这样:

<cars>
    <car id="9" follows="34" />
    <car id="12" follows="20" />
    <car id="20" follows="9" />
    <car id="29" follows="30" />
    <car id="30" />
    <car id="34" follows="29" />
</cars>

...给出30,29,34,9,20,12的排序。我正在使用.NET的LinkedList类来构建一个反映这些数据的链表,但构建起来很尴尬因为这些值不按顺序排列。我真正想要做的是假设数据是有效的 - 只有一个第一个值,而所有其他值都跟随列表中另一个节点的“跟随”值。像这样的代码会很好(FindFirstForwards是我写的自定义扩展方法,用于查找给定lambda返回true的第一个链表项:)

LinkedList<CarInstance> orderedCars = new LinkedList<CarInstance>();
XPathNodeIterator xmlIterator = _nav.Select("/dflt:cars/dflt:car", _namespaceResolver);
while (xmlIterator.MoveNext()) {
    if (!(xmlIterator.Current.Select("@follows").Count > 0)) {
        orderedCars.AddFirst(new CarInstance {
            CarId = int.Parse(xmlIterator.Current.GetAttribute("id", _defaultNamespace))
        });
    }
    else {
        orderedCars.AddAfter(orderedCars.FindFirstForwards(car => car.CarId == int.Parse(xmlIterator.Current.GetAttribute("follows", _defaultNamespace))), new CarInstance {
            CarId = int.Parse(xmlIterator.Current.GetAttribute("id", _defaultNamespace))
        });
    }
}

问题是,如果此车所遵循的汽车尚未添加到orderedCars,则会引发异常,因为FindFirstForwards未找到具有“跟随”ID的汽车。我真正想要做的是“将其添加到链接列表中,假设它将跟随某个ID的未来条目,即使该条目尚未添加,并继续。”然后在最后,检查链表的完整性,以确保每个节点指向另一个节点,并且有一个头节点。

有简洁的方法吗?如果不是,那么将这种XML转换为内存链表的最有效(最好是代码简洁)方法是什么?

1 个答案:

答案 0 :(得分:4)

我会以两步的方式做到这一点:

  1. 将所有车辆加载到字典中,按车辆ID键入,而不考虑订购
  2. 通过循环连接所有汽车(按字典顺序,无关紧要),并通过字典找到以下汽车,此时应该是O(1)操作。
  3. 如果你不能在没有将下一辆车挂在那里的情况下构造一个汽车对象,即。汽车对象的“跟随”部分(或全部)是不可变的,我会创建一个临时类,甚至将XML节点存储在字典中,然后在订购后构建汽车对象。

    此外,即使您只有一个从一个对象到另一个对象的链接,您也可以考虑使用拓扑排序,但请注意,此算法的快速实现通常也使用字典。