从链表标签wiki摘录中:
链表是一种数据结构,其中的元素包含对下一个(和可选的上一个)元素的引用。链表提供O(1)在任何位置插入和删除、O(1)列表连接以及O(1)在前面(和可选的后面)位置访问和O(1)下一个元素访问。随机访问具有O(N)复杂度,并且通常未实现。
(强调我的)
我很惊讶地看到这个 - 如何在随机索引处插入比仅仅读取该索引具有更低的复杂度?
所以我查看了 Java.util.LinkedList 的源代码。add(int, E)
方法 为:
public void add(int index, E element) {
addBefore(element, (index==size ? header : entry(index)));
}
addBefore(E, Entry<E>
方法 只是指针重新赋值,但还有一个 entry(int)
方法:
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
Entry<E> e = header;
if (index < (size >> 1)) {
for (int i = 0; i <= index; i++)
e = e.next;
} else {
for (int i = size; i > index; i--)
e = e.previous;
}
return e;
}
即使进行了一半的优化,这里的for循环(其中之一)对我来说似乎是一个明显的线索,表明此方法(因此
add(int, E)
)在最坏情况下的时间复杂度为O(n),而不是常数时间。我错过了什么吗?我是否误解了大O符号?