Quali sono le regole concrete per l'utilizzo di un elenco collegato anziché di un array?


18

Un elenco collegato può essere utilizzato quando si desidera l'inserimento e l'eliminazione di elementi a basso costo e quando non importa che gli elementi non siano uno accanto all'altro in memoria.

Questo è molto astratto e vorrei una spiegazione concreta del perché un elenco collegato dovrebbe essere usato piuttosto che un array. Non ho molta esperienza con la programmazione, quindi non ho molta esperienza nel mondo reale.


3
Onestamente, non credo che gli esempi significheranno molto per te fino a quando non avrai una certa esperienza di scrittura di qualcosa e quindi di vedere l'effetto che il cambiamento delle strutture di dati ha sul tuo codice. O prova a scrivere qualcosa che ti interessa, e scopri quali strutture e contenitori di dati sono più adatti, oppure guarda un po 'di codice esistente e pensa al motivo per cui ciascun contenitore è stato selezionato e quale effetto avrebbe cambiato.
Inutile

Non credo sia possibile comunicare utilmente i compromessi e gli effetti collaterali della selezione della struttura dei dati all'OP (inesperto) senza un esempio di forma molto più lunga di quanto sia ragionevole qui. Gli esempi forniti come risposte vanno bene e rispondono alla domanda come posta, ma non (ciò che leggo come) una richiesta implicita per la comprensione effettiva.
Inutile

Risposte:


37

Ecco qualcosa a metà strada tra un esempio e un'analogia. Hai qualche commissione da fare, quindi prendi un pezzo di carta e scrivi:

  • banca
  • drogheria
  • lasciare lavare a secco

Quindi ti ricordi che devi anche comprare francobolli. A causa della geografia della tua città, devi farlo dopo la banca. È possibile copiare l'intero elenco su un nuovo pezzo di carta:

  • banca
  • francobolli
  • drogheria
  • lasciare lavare a secco

o potresti scarabocchiare su quello che avevi:

  • banca ....... TIMBRI
  • drogheria
  • lasciare lavare a secco

Mentre pensavi ad altre commissioni, potresti scriverle in fondo all'elenco, ma con le frecce che ti ricordano in quale ordine eseguirle. Questa è una lista collegata. È più veloce e più semplice che copiare l'intero elenco ogni volta che aggiungi qualcosa.

Poi il tuo cellulare squilla mentre sei in banca "ehi, ho i francobolli, non raccogliere più". Basta cancellare STAMPS dall'elenco, non riscriverne uno completamente nuovo senza STAMPS.

Ora potresti effettivamente implementare un elenco di commissioni nel codice (forse un'app che mette in ordine le tue commissioni in base alla tua area geografica) e c'è una ragionevole possibilità che tu utilizzi effettivamente un elenco collegato per quello nel codice. Volete aggiungere e rimuovere molti articoli, ordinare questioni, ma non volete ricopiare l'intero elenco dopo ogni inserimento o cancellazione.



@Dennis sì, lo so, grazie a spostare la semantica. Tuttavia, questo non è vero per tutte le lingue, quindi l'esempio vale.
Kate Gregory,

1
@KateGregory è abbastanza giusto, ma è comunque bene sottolineare che le strutture di dati "di base" sono spesso migliori delle strutture di dati interessanti di cui apprendiamo a scuola (o altrove). Non voglio che i nuovi laureati usino LL ovunque perché è teoricamente appropriato pur essendo realisticamente una cattiva scelta. L'uso della giusta struttura di dati è importante e talvolta le persone lo complicano eccessivamente. Leggermente correlato è questo discorso di Jonathan Blow (creatore di "Braid") sulle strutture di dati .
Dennis,

1
@Ray: un elenco collegato può sovraperformare una struttura ad albero se ci si aspetta che ci sia nell'ordine di 4 elementi e i confronti sono relativamente economici. Non so esattamente dove sia il cut-off dove questo non è il caso. Inoltre, una struttura ad albero richiede che i dati possano essere ordinati, mentre una struttura di elenco consente di mantenere l'ordine di inserimento (o qualsiasi ordine arbitrario).
David Stone,

2
Non penso che questa analogia sia molto accurata. Come umani, possiamo (almeno per un elenco così breve) trovare un elemento in O (1). Ma se vuoi fare un inserimento casuale in un elenco collegato, dovrai attraversare in media metà degli elementi che ti costano O (n) solo per trovare la posizione in cui vuoi inserire. L'inserto effettivo costa quindi solo O (1) ma con un array, il costo è anche "solo" O (n). Quindi la ragione non è dovuta solo alla mossa semantica ma algoritmica. Il fattore costante nascosto dal big-O è molto più grande per l'elenco dei preferiti, tuttavia, a causa dell'accesso alla memoria non contiguo.
5gon12eder,

18
  • Gli hashtable che utilizzano il concatenamento per risolvere le collisioni di hash in genere hanno un elenco collegato per bucket per gli elementi in quel bucket.
  • Gli allocatori di memoria semplici utilizzano un elenco gratuito di aree di memoria non utilizzate, sostanzialmente un elenco collegato con il puntatore dell'elenco all'interno della memoria libera stessa
  • In un file system FAT , i metadati di un file di grandi dimensioni sono organizzati come un elenco collegato di voci FAT.

12

Lo "stack di chiamate" in linguaggio C è implementato come un elenco collegato nelle API binarie x86 (e nella maggior parte degli altri).

Cioè, la procedura di chiamata in linguaggio C segue una disciplina first-in, last-out. Il risultato dell'esecuzione (possibilmente ricorsiva) delle chiamate di funzione viene definito "stack di chiamate", o talvolta persino "stack".

L' CALListruzione x86 finisce per impiantare un elenco collegato usando lo "stack di chiamate". CALLUn'istruzione spinge il contenuto del registro% PEI, l'indirizzo dell'istruzione dopo il CALLsulla memoria stack. Il prologo chiamato fuction inserisce il contenuto del registro% EBP, l'indirizzo più basso delle variabili locali nella funzione chiamante, nella memoria dello stack. Quindi il prologo della funzione chiamata imposta% EBP sulla base dello stack della funzione corrente.

Ciò significa che% EBP è un puntatore a una posizione di memoria che contiene l'indirizzo del valore% EBP della funzione chiamante. Non è altro che un elenco collegato, implementato parzialmente nell'hardware tramite CALL.

Per quanto riguarda ciò, è il modo in cui le CPU x86 implementano le chiamate di funzione, in particolare le chiamate di funzione in cui la funzione ha una propria copia di argomenti e variabili locali alla funzione. Ogni chiamata di funzione invia alcune informazioni sullo "stack di chiamate" che consente alla CPU di riprendere da dove si era interrotta nella funzione di chiamata, senza interferenze da parte della funzione chiamata o della funzione chiamante.


3

Un elenco collegato può essere utilizzato per implementare una coda di messaggi.

Una coda di messaggi è una struttura in cui archiviamo informazioni sugli eventi per successive elaborazioni. Ad esempio, quando l'utente preme un tasto o sposta il mouse, questo è un evento. Un'applicazione potrebbe essere occupata nel momento in cui si verifica l'evento, quindi non ci si può aspettare che elabori l'evento nel momento esatto in cui si verifica. Pertanto, l'evento viene inserito in una coda di messaggi (informazioni su quale tasto è stato premuto o su dove si è spostato il mouse) e quando l'applicazione ha del tempo libero, controlla la coda dei messaggi, recupera gli eventi da esso ed elabora loro. (Ciò accade in un arco di tempo di millisecondi, quindi non è evidente.)

Dallo scenario di utilizzo che ho appena descritto, dovrebbe essere ovvio che non ci interessa avere accesso casuale agli eventi memorizzati nella coda dei messaggi; ci interessa solo essere in grado di archiviare i messaggi in esso e recuperarli. Pertanto, ha senso utilizzare un elenco collegato, che fornisce tempi di inserimento / rimozione ottimali.

(Si prega di non inserirsi per sottolineare che una coda di messaggi è probabile, o più probabile, o quasi altrettanto probabile, essere implementata utilizzando un elenco di array circolare; questo è un dettaglio tecnico e ha una limitazione: è possibile solo memorizzare un numero limitato di messaggi al suo interno.)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.