【问题标题】:Help choosing the right data structure帮助选择正确的数据结构
【发布时间】:2010-05-31 16:24:54
【问题描述】:

我需要一个满足以下要求的数据结构:

  1. 需要能够按索引获取元素(如列表)。
  2. 我将始终只在结构末尾添加/删除元素。

我倾向于使用ArrayList。在这种情况下,似乎O(1) 既要读取元素(它们总是?),删除元素(我只需要在列表末尾删除它们)和添加(我只添加到末尾列表)。

唯一的问题是,当 ArrayList 完全填满时,有时会出现性能损失,我需要向其中添加更多元素。

还有其他更好的主意吗?我不认为有一种数据结构会在这里击败ArrayList

谢谢

【问题讨论】:

    标签: c# java data-structures


    【解决方案1】:

    听起来不错,但在 C# 中您应该使用 List<T>。它是ArrayList<E> 的Java 等价物。 C# 中的 ArrayList 类不是通用的,基本上被新的 List<T> 类淘汰了。

    唯一的问题是,当 ArrayList 完全填满时,有时会出现性能损失,我需要向其中添加更多元素。

    这可能不会成为问题,除非您已进行性能分析,否则您可能不应该担心它。但是,如果您事先知道(或可以猜到)列表将包含的元素数量,您可以将其 Capacity 设置为该值(Java 中的 ensureCapacity)。这将导致列表提前保留所需的内存。你也可以给bothlanguages中的列表构造函数提供容量。

    【讨论】:

      【解决方案2】:

      使用 ArrayList。

      如您所说,当它达到其容量限制时,它将动态调整大小。然而这应该不是问题,因为它使用了一个足够聪明的算法,每次追加操作的平均成本仍然只有 O(1)。

      【讨论】:

        【解决方案3】:

        始终使用 List<T> 而不是 ArrayList

        【讨论】:

        • 不,错了!你没看懂问题。关键是提问者想知道他应该实际使用 List 的哪个具体 Java 实现。如果这是关于 C#,那么我将收回反对票。
        • 是的,这仅适用于 C# :) 谁使用 Java? :)
        • 是的,我应该提前注意到 Java 和 C# 的实现/名称是不同的 :(
        • 所以您的帖子是为了阅读“使用 C# 而不是 Java”?对毫无意义的宗教战争投反对票。
        【解决方案4】:

        实际上添加可能更多 O(N),因为当数组增长超过分配限制时必须重新分配和复制。 Javadocs 指定它以 O(N) 的摊销成本增长,无论这意味着什么,正如我所期望的 O(NlogN) 但显然它们的算法比我知道的更智能。

        如果您在构建时分配足够的元素来包含完整的集合,则为 O(1)。

        见:http://java.sun.com/j2se/1.4.2/docs/api/java/util/ArrayList.html

        【讨论】:

        • 虽然完整的数组分配是 O(N),但每次添加的摊销成本仅为 O(1)。他们通过以指数比例因子增长数组来做到这一点(这意味着完全重新分配的发生频率呈指数下降)
        【解决方案5】:

        您需要平衡对List<T> 的读取访问与写入访问的相对频率。必须注意的是,对于大多数用途,您不太可能注意到调整 ArrayList<T> 大小的成本

        但是,如果您在最后一次添加和删除一个项目,那么您将按索引获取项目(基本上使用列表作为StackQueue)并且您的分析器会告诉您ArrayList<T> 是您的性能瓶颈所在,您应该考虑使用专门用于此类用途的 LinkedList<T>

        【讨论】:

        • 在访问最后一个元素的 LinkedList 上,读写操作都很慢。但是,对于双链表,情况就不同了。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-25
        • 2021-12-03
        相关资源
        最近更新 更多