【问题标题】:More appropriate to say Amortized O(1) vs O(n) for insertion into unsorted dynamic array?更适合说 Amortized O(1) vs O(n) 插入未排序的动态数组?
【发布时间】:2015-04-07 06:58:12
【问题描述】:

这属于 stackoverflow.com/help/on-topic 中的“软件算法”,在这种情况下,是一种将项目添加到动态未排序数组的软件算法

这是我们在课堂上制作的关于不同数据结构的操作运行时间的图表

我的问题是关于将值插入(或添加)到动态未排序数组的运行时。 这是我们执行此操作的代码

 public void insert(E value) {
    ensureCapacity(size + 1);
    elementData[size] = value;
    size++;
}
  private void ensureCapacity(int capacity) {
    if (capacity > elementData.length) {
        int newCapacity = elementData.length + 100;
        if (capacity > newCapacity) {
            newCapacity = capacity;
        }
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
}

我理解这可以解释为 O(n)。 ensureCapacity 函数在技术上是由插入和运行时分析组成的操作的一部分,https://academics.tjhsst.edu/compsci/CS2C/U2/bigoh.html,你会说两个分支的最坏情况是原始数组的每个元素都被复制到新数组中,即O(n) 操作。所以整个函数的最坏情况或大哦是O(n)

是否也可以为摊销 O(1) 时间进行论证(What is amortized analysis of algorithms?),因为每次调整大小时,您都必须等待特定的时间才能进行下一次调整?

在那个图表中,那么 O(1) 是否也有意义?

【问题讨论】:

    标签: java algorithm arraylist time-complexity amortized-analysis


    【解决方案1】:

    没有。

    “Amortized O(1) time”意味着一个非常具体的东西——它意味着一次插入 n 个项目的成本是 O(n)。仅仅说“需要很长时间的事情不会经常发生”是不够的——你实际上必须从数学上分析算法。

    这种特殊情况(将项目插入数组,或者如果已满则调整其大小)是众所周知的。事实证明,如果您通过一个常数 factor 调整数组的大小(例如,每次满时都将其加倍),那么此操作将摊销 O(1)。如果您添加固定数量的元素(例如,每次满时添加 100),那么它仍然摊销 O(n),因为它需要 O(n2) 时间分别添加 n 个元素。

    【讨论】:

    • 你说“单独添加 n 个元素需要 O(n^2) 时间”是什么意思。那不应该只是 O(n) 因为您只是将元素从旧数组移动到新数组吗?
    • @committedandroider 如果您创建一个新的动态数组(使用您的代码)并添加 50,000,000 个元素,则所需时间大约是您仅添加 25,000,000 个元素的 4 倍。 (显然 O(n) 和 O(n^2) 的实际定义并没有使用“约”这个词,但这已经足够接近了)
    • 你怎么知道它需要 4 倍的时间?
    • @committedandroider 如果你将 n 设为两倍,那么 n^2 将设为 4 倍。
    • @committedandroider - 如果你想真正理解,自己算算。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 2015-09-28
    • 1970-01-01
    • 2015-06-25
    • 2013-06-26
    相关资源
    最近更新 更多