对于插入未排序的动态数组,更适合使用Amortized O(1)vs O(n)?

时间:2015-02-07 01:32:33

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

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

这是我们在课堂上关于不同数据结构enter image description here

上的操作运行时间的图表

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

 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函数在技术上是由insert和运行时分析https://academics.tjhsst.edu/compsci/CS2C/U2/bigoh.html组成的操作的一部分,你会说两个分支的最坏情况是当原始数组的每个元素被复制到新数组中时这是一个O(n)操作。所以整个函数的最坏情况或大哦是O(n)

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

在那张图表中,O(1)也会有意义吗?

1 个答案:

答案 0 :(得分:7)

没有

"摊销O(1)时间"意味着一个非常具体的东西 - 这意味着一次一个地插入 n 项目的成本是O(n)。仅仅说那些需要很长时间才能经常发生的事情是不够的。 - 你实际上必须以数学方式分析算法。

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