在书data structures and algorithms的第290页中,提到了arraylist的remove(i)的复杂性是O(1)。我的第一个问题是为什么不是O(n)?还提到add(i,e)链表是O(n),所以我的第二个问题是为什么不是O(min(i,n-i))?
最后,我的第三个问题是提到复杂性的原因,因为O(min(i,ni))是由于是一个双向链表,这意味着我们可以从开始(i)或结束(ni)遍历?
答案 0 :(得分:1)
第一个是值得商榷的。当您删除ArrayList中的最后一个元素时,它是常量,但对于中间元素,您需要将所有后继元素移到左侧。 Java使用System.arrayCopy()这是一个非常快速的本机例程来复制数组,但即使是那个方法显然是O(n),也不是常数,所以我倾向于同意你的看法。对于插入来说,它是不同的,其中将数组大小调整到所需索引的分摊成本平均为常数因子,因此add()为O(1)。
第二个可以通过这种方式实现,但事实并非如此。删除仅从头开始。我猜测是通过不同步访问来减少事故的。
最后,在Big-O复杂性的符号中,不太重要的因素被丢弃,所以O(min(i,ni))实际上相当于O(n),即使现实世界告诉我们前者肯定会是一种优化。