【问题标题】:Java: Inserting into LinkedList efficientlyJava:有效地插入 LinkedList
【发布时间】:2012-04-15 22:52:45
【问题描述】:

我正在优化排序的 LinkedList 的实现。

要插入一个元素,我会遍历列表并比较每个元素,直到获得正确的索引,然后中断循环并插入。

我想知道是否有任何其他方法可以在遍历列表的同时插入元素以将插入从 O(n + (n capped at size()/2)) 减少到 O (n)。

ListIterator 几乎是我所追求的,因为它的 add() 方法,但不幸的是,在列表中有元素等于插入的情况下,插入必须放在它们之后在列表中。要实现这个 ListIterator 需要一个它没有的 peek()。

编辑:我有我的答案,但无论如何都会添加这个,因为很多人还没有正确理解: 我正在寻找一个插入点 AND 插入,它的总和高于 O(n)

【问题讨论】:

  • 为什么不使用 Multiset?
  • 我不明白为什么迭代列表并在小于或等于插入元素的最后一个元素之后插入将具有超过 O(n) 的复杂性。在链表中,它基本上只是迭代,直到找到插入点(即 O(n)),然后在该点插入(即 O(1))。
  • 另外:为什么不使用平衡二叉树而不是排序链表?这应该将插入成本降低到 O(log(n))(搜索插入点的成本)。
  • @Thomas 因为我遍历列表以查找索引,而 LinkedList.insert(index, element) 遍历列表以插入。
  • 您的语句“优化排序的LinkedList 实现”包含至少两个内部矛盾。

标签: java list linked-list big-o doubly-linked-list


【解决方案1】:

我有我的答案,但无论如何都会添加这个,因为很多人还没有正确理解:我正在搜索插入点和插入,它的总和高于O(n)

您需要维护一组(可能)非唯一元素,这些元素可以按照排序函数给出的顺序进行迭代。这可以通过多种方式实现。 (在下文中,我使用“总插入成本”来表示将多个 (N) 元素插入到最初为空的数据结构中的成本。)

  • 单向或双向链表提供O(N^2) 总插入成本(无论您是否结合查找位置和执行插入的步骤!)和O(N) 迭代成本。

  • TreeSet 提供O(NlogN) 总插入成本和O(N) 迭代成本。但有不重复的限制。

  • 基于树的多重集(例如TreeMultiset)与 TreeSet 具有相同的复杂性,但允许重复。

  • skip-list 数据结构也具有与前两种相同的复杂性。

显然,复杂性度量表明,当 N 变大时,使用链表的数据结构表现最差。对于这组特定的需求,一个良好实现的基于树的多重集可能是最好的,假设只有一个线程访问该集合。如果集合被许多线程大量使用(并且它是一个集合),那么ConcurrentSkipListSet 可能会更好。


您似乎也对“大 O”度量如何组合存在误解。如果我有一个算法的一个步骤是O(N),而第二个步骤也是O(N),那么这两个步骤组合起来仍然是O(N) ....而不是“超过O(N)”。您可以从“大 O”的定义中得出这一点。 (我不会让你厌烦细节,但数学很简单。)

【讨论】:

    【解决方案2】:

    我赞成 Péter Török 的建议,但我仍然想为迭代器方法添加一些内容:

    请注意,ListIterator 提供了一个 previous() 方法来向后遍历列表。因此首先迭代直到找到第一个更大的元素,然后转到前一个元素并调用add(...)。如果您到达终点,即所有元素都较小,则只需调用 add(...) 而无需返回。

    【讨论】:

      【解决方案3】:

      您可以考虑使用skip list,它使用多个不同粒度的链表实现。例如。第 0 级的链表包含所有项目,第 1 级平均仅链接到每个第 2 个项目,第 2 级平均仅链接到第 4 个项目,等等....搜索从顶层开始,逐渐下降到较低级别,直到它找到完全匹配。这个逻辑类似于二分查找。因此搜索和插入是一个 O(log n) 操作。

      Java 类库中的一个具体示例是ConcurrentSkipListSet(尽管在这里可能无法直接使用)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多