Dal linked-list tag wiki estratto:In che modo LinkedList aggiunge (int, E) di complessità O (1)?
Una lista concatenata è una struttura dati in cui gli elementi contengono riferimenti alla (e facoltativamente il precedente) all'elemento successivo. Collegati elenchi offrono O (1) inserire e rimozione in qualsiasi posizione, O (1) Lista concatenazione, e O (1) l'accesso alla parte anteriore (e facoltativamente schienale) posizioni e O (1) all'elemento successivo accesso. L'accesso casuale ha la complessità O (N) e di solito non è implementato.
(sottolineatura mia)
Sono rimasto sorpreso di leggere questo – come può l'elenco inserire ad un indice caso con una complessità inferiore a quello semplicemente lettura tale indice?
Così ho visto the source code for java.util.LinkedList
. Il add(int, E)
method è:
public void add(int index, E element) {
addBefore(element, (index==size ? header : entry(index)));
}
Il addBefore(E, Entry<E>
method è semplicemente puntatore riassegnazione, ma c'è anche la entry(int)
method:
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;
}
Anche con l'ottimizzazione half-size, il ciclo for
qui (uno o l'altro) mi sembra un dono morto che questo metodo (e quindi add(int, E)
) opera in uno scenario minimo nel caso peggiore di tempo O (n), e certamente non costante.
Cosa mi manca? Sto fraintendendo la notazione O grande?
In altre parole: 'LinkedList .add (int, E)' non è O (1), ma 'ListIterator .add' è (per gli iteratori che provengono da un' LinkedList'). –
sepp2k