【问题标题】:Most efficient way to construct a linked list from stored data?从存储的数据构造链表的最有效方法?
【发布时间】:2012-12-22 05:08:57
【问题描述】:

我将数据存储在描述链接列表的 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 转换为内存链表的最有效(最好是代码简洁)的方法是什么?

【问题讨论】:

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


    【解决方案1】:

    我会分两步进行:

    1. 将所有汽车加载到一个字典中,以汽车的 ID 为键,而不考虑它们的顺序
    2. 通过遍历所有汽车(按字典顺序,无关紧要)连接所有汽车,并通过字典找到以下汽车,此时应该是 O(1) 操作。

    如果你不能在没有将下一辆车链接到该点的情况下构造汽车对象,即。汽车对象的“跟随”部分(或全部)是不可变的,我会创建一个临时类,甚至将 XML 节点存储在字典中,然后在您获得它们的顺序后构造汽车对象。

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

    【讨论】:

    • +1。几乎是最好的事情。要验证链接,您必须进行快速的关系查找,并且列表很糟糕 - 字典会发光。将它们加载到字典中,然后从那里取出。
    猜你喜欢
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-06
    相关资源
    最近更新 更多