2009-04-27 11 views
8

Sono uno studente di informatica in Germania. Il mio professore ha dato utilizzare la seguente domanda a cui pensare:Algoritmo per l'eliminazione di un elemento in una sola lista collegata con O (1) la complessità

'Dato un riferimento ad un nodo in una sola lista collegata (che non è l'ultimo nodo). Dare un algoritmo per eliminare questo elemento dalla lista che ha complessità O (1) pur mantenendo l'integrità '.

ho pensato a questo, ma sono abbastanza sicuro, che non v'è tale algoritmo. poiché si tratta di un singolo elenco collegato, è necessario eseguire il ciclo di ogni nodo nell'elenco fino a raggiungere il nodo che deve essere eliminato, poiché è necessario modificare il puntatore successivo nel nodo prima dell'eliminazione. Quale porterebbe a O (n) complessità.

Mi sto perdendo qualcosa?

risposta

24

Dipende se i nodi sono mutabili (valore).

Ci è un modo di fare che, se si può fare quello che vuoi con i nodi:

toDelete.value = toDelete.next.value 
toDelete.next = toDelete.next.next 

Tutte le informazioni dal toDelete è ora stato sovrascritto, dalle informazioni nella vecchia toDelete.next. (A seconda della piattaforma, potrebbe essere necessario liberare il vecchio toDelete.next - il che significa mantenere un riferimento temporaneo ad esso. Non va bene se qualcun altro ha ancora un riferimento ad esso, ovviamente. In Java/C# lo ignoreresti .)

ho cercato di trovare un modo di accennare a esso senza darlo via, ma è un po 'complicato ...

essa si basa su questo non essere l'ultimo nodo della lista però.

+0

Ah, capito. Grazie :) –

+0

fai attenzione, come ha spiegato Jon, che affinché funzioni, la struttura del nodo deve essere privata. Nessuno dovrebbe tenere un riferimento ai nodi stessi, solo ai dati. In caso contrario, i consumatori resterebbero con un riferimento non valido al vecchio oggetto toDelete.next (se si è in C++ per esempio e si è eliminata la struttura del nodo), o nella migliore delle ipotesi un oggetto nodo non valido. –

+0

Questo non è proprio un 'algoritmo' per rimuovere un elemento da una lista collegata singolarmente vero? Questo è il metodo standard per rimuovere un elemento dall'elenco. – Dinuk

8

Non esattamente considerato l'eliminazione di un nodo, ma è possibile copiare i dati del nodo successivo alla corrente ed eliminare il nodo successivo:

// pseudocode: 
this.data = next.data; 
var temp = this.next; 
this.next = next.next; 
delete temp; 
2

Sì. Si mantiene come puntatore iteratore, un puntatore al puntatore successivo dell'elenco precedente.

walk = &head; 
while (!match(*walk)) { 
    walk = &walk[0]->next; 
    if (!*walk) return ; 
} 
*walk = walk[0]->next; 
+0

Questo non è O (1) però. –

+0

La parte rimossa è. Un iteratore di aggiornamento su un elenco collegato dovrebbe * sempre * usare il puntatore al puntatore al nodo successivo. – Joshua

3

Se i nodi sono strutture di base in memoria, è possibile copiare il contenuto del nodo "successivo" nella locazione di memoria del nodo cancellato, e deallocare la memoria in cui il nodo "next" di una volta.

2

si Supponendo che avete il puntatore al nodo che si desidera eliminare. Replica il valore successivo nel nodo corrente. Sostituisci il puntatore corrente sul nodo il prossimo a cui si fa riferimento.