Из linked-list tag wiki excerpt
Связанный список - это структура данных, в которой содержатся элементы ссылки на следующий (и, возможно, предыдущий) элемент. связанный списки предлагают O (1) вставку и удаление в любой позиции, список O (1) конкатенация и O (1) доступ спереди (и, возможно, обратно) а также O (1) доступ к следующему элементу. Случайный доступ имеет O (N) сложность и обычно не реализуется.
(акцент мой)
Я был удивлен, прочитав это & ndash; как список может вставляться в случайный индекс с меньшей сложностью, чем просто читать этот индекс?
Итак, я посмотрел исходный код 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) и, конечно, не постоянное время.
Что мне не хватает? Неужели я неправильно понимаю обозначение Big-O?