Matrice contro elenco collegato


200

Perché qualcuno dovrebbe voler utilizzare un elenco collegato su un array?

La codifica di un elenco collegato è, senza dubbio, un po 'più impegnativa rispetto all'utilizzo di un array e ci si potrebbe chiedere cosa giustificherebbe lo sforzo aggiuntivo.

Penso che l'inserimento di nuovi elementi sia banale in una lista collegata, ma è un lavoro importante in un array. Ci sono altri vantaggi nell'utilizzare un elenco collegato per archiviare un set di dati rispetto alla loro memorizzazione in un array?

Questa domanda non è un duplicato di questa domanda perché l'altra domanda si pone specificamente su una particolare classe Java mentre questa domanda riguarda le strutture di dati generali.


1
Correlati - Quando utilizzare LinkedList <> su ArrayList <>? - è Java, ma gli array (ArrayList) e gli elenchi collegati presumibilmente hanno le stesse prestazioni in qualsiasi lingua.
Bernhard Barker,


1
@rootTraveller In realtà quella domanda sarebbe un duplicato di questa domanda perché la mia domanda è stata pubblicata per prima.
Onorio Catenacci,

Risposte:


147
  • È più facile archiviare dati di dimensioni diverse in un elenco collegato. Un array presuppone che ogni elemento abbia esattamente le stesse dimensioni.
  • Come hai detto, è più facile che un elenco collegato cresca organicamente. Le dimensioni di un array devono essere conosciute in anticipo o ricreate quando devono crescere.
  • Mescolare un elenco collegato è solo una questione di cambiare ciò che punta a cosa. Mescolare un array è più complicato e / o richiede più memoria.
  • Finché le iterazioni avvengono tutte in un contesto "foreach", non si perde alcuna performance nell'iterazione.

19
In che modo vengono trattati in modo diverso articoli di dimensioni diverse? Un elenco collegato utilizza una struttura fissa con un campo successivo (richiede una dimensione fissa) o memorizza un puntatore ai dati nell'auto (dimensione variabile OK). Entrambi gli approcci sono altrettanto semplici con un vettore. Lo stesso per mescolare.
Brian,

32
Direi che mescolare un array è meno complicato.
Hugh Allen,

23
Questa risposta è errata e fuorviante. (tranne che per la necessità di conoscere le dimensioni di un array quando lo dichiarate)
Robert Paulson,

35
L'iterazione di un elenco collegato non sarebbe più lenta a causa della localizzazione dei dati?
Firas Assaad,

6
@Rick, i vettori in genere sovrallocano lo spazio richiesto in modo che non debbano allocare nuovo spazio ogni volta che la dimensione aumenta. Il risultato è che i vettori in genere richiedono molta meno memoria, non più degli elenchi collegati.
Winston Ewert,

179

Un altro buon motivo è che gli elenchi collegati si prestano bene a implementazioni multi-thread efficienti. La ragione di ciò è che le modifiche tendono ad essere locali, interessando solo un puntatore o due per l'inserimento e la rimozione in una parte localizzata della struttura dei dati. Quindi, puoi avere molti thread che lavorano sullo stesso elenco collegato. Ancora di più, è possibile creare versioni senza blocco utilizzando operazioni di tipo CAS ed evitare del tutto i blocchi pesanti.

Con un elenco collegato, gli iteratori possono anche attraversare l'elenco mentre si verificano modifiche. Nel caso ottimistico in cui le modifiche non si scontrano, gli iteratori possono continuare senza contese.

Con un array, è probabile che qualsiasi modifica che modifichi le dimensioni dell'array richieda il blocco di gran parte dell'array e, in effetti, è raro che ciò avvenga senza un blocco globale nell'intero array, in modo che le modifiche diventino fermare gli affari del mondo.


9
Alex - questa è una considerazione interessante che non mi sarebbe mai venuta in mente. Ottima risposta Ti voto due volte se potessi. :-)
Onorio Catenacci,

5
Dai un'occhiata agli skip list (in particolare ConcurrentSkipListMap in Java 6) per una buona idea di dove puoi andare con questo. CSLM è una mappa ordinata e simultanea con prestazioni eccellenti. Molto, molto meglio di una TreeMap sincronizzata. tech.puredanger.com/2007/10/03/skip-lists
Alex Miller,

... tranne che ConcurrentSkipListMapo ConcurrentSkipListMapnon sono elenchi, anche se "Elenco" compare da qualche parte nel loro nome. Entrambi richiedono chiavi che saranno ordinate e uniche. Se hai bisogno di un List, cioè quella struttura di dati che consente elementi duplicati in un ordine arbitrario, non è adatto e dovresti fare di tutto per creare una struttura di dati come LinkedListuna cosa aggiornabile contemporaneamente. Se hai solo bisogno di una coda o di una coda simultanea, beh sì, ci sono anche esempi esistenti, ma una simultanea List... Non sono convinto che ciò sia persino possibile.
Holger,

128

Wikipedia ha un'ottima sezione sulle differenze.

Gli elenchi collegati presentano numerosi vantaggi rispetto agli array. Gli elementi possono essere inseriti in elenchi collegati indefinitamente, mentre un array alla fine si riempie o deve essere ridimensionato, un'operazione costosa che potrebbe non essere possibile anche se la memoria è frammentata. Allo stesso modo, un array da cui vengono rimossi molti elementi può diventare inutilmente vuoto o deve essere ridotto.

D'altra parte, gli array consentono l'accesso casuale, mentre gli elenchi collegati consentono solo l'accesso sequenziale agli elementi. Gli elenchi collegati singolarmente, infatti, possono essere attraversati solo in una direzione. Ciò rende gli elenchi collegati non adatti alle applicazioni in cui è utile cercare rapidamente un elemento in base al suo indice, ad esempio heapsort. L'accesso sequenziale su array è anche più veloce rispetto agli elenchi collegati su molte macchine a causa della localizzazione delle cache di riferimento e dei dati. Gli elenchi collegati non ricevono quasi alcun vantaggio dalla cache.

Un altro svantaggio degli elenchi collegati è la memoria aggiuntiva necessaria per i riferimenti, che spesso li rende poco pratici per elenchi di piccoli elementi di dati come caratteri o valori booleani. Può anche essere lento e con un allocatore ingenuo, dispendioso, allocare la memoria separatamente per ogni nuovo elemento, un problema generalmente risolto usando i pool di memoria.

http://en.wikipedia.org/wiki/Linked_list


4
Questa è la risposta perfetta Descrive in modo succinto i vantaggi e gli svantaggi di entrambi.
Rick,

grazie)) morto semplice ma non l'ho visto nel wiki)
Timur Fayzrakhmanov

58

Ne aggiungerò un altro: le liste possono agire come puramente funzionali strutture di dati .

Ad esempio, puoi avere elenchi completamente diversi che condividono la stessa sezione finale

a = (1 2 3 4, ....)
b = (4 3 2 1 1 2 3 4 ...)
c = (3 4 ...)

vale a dire:

b = 4 -> 3 -> 2 -> 1 -> a
c = a.next.next  

senza dover copiare i dati indicati da ain bec .

Questo è il motivo per cui sono così popolari nei linguaggi funzionali, che usano variabili immutabili - prepende le tailoperazioni possono avvenire liberamente senza dover copiare i dati originali - caratteristiche molto importanti quando si trattano i dati come immutabili.


4
Ancora un'altra considerazione molto interessante che non mi sarei mai inventato. Grazie.
Onorio Catenacci,

Come posso farlo in Python?
Scambio eccessivo del

29

Oltre ad essere più facile da inserire al centro dell'elenco, è anche molto più facile eliminare dal centro di un elenco collegato piuttosto che un array.

Ma francamente, non ho mai usato un elenco collegato. Ogni volta che avevo bisogno di inserimento e cancellazione veloce, avevo anche bisogno di una ricerca veloce, quindi sono andato a un HashSet o un dizionario.


2
Molto vero, l'inserimento e l'eliminazione avvengono dopo la ricerca per la maggior parte del tempo, quindi è necessario considerare anche la somma delle complessità temporali.
MA Hossain Tonu,

28

L'unione di due elenchi collegati (in particolare due elenchi doppiamente collegati) è molto più rapida rispetto all'unione di due array (supponendo che l'unione sia distruttiva). Il primo prende O (1), il secondo prende O (n).

EDIT: Per chiarire, intendevo "fondere" qui in senso non ordinato, non come in ordine di fusione. Forse "concatenare" sarebbe stata una parola migliore.


2
Solo se stai semplicemente aggiungendo un elenco all'altro. Se stai effettivamente unendo due elenchi ordinati, ci vorrà un registro più di O (1).
Herms,

3
@Herms, ma puoi unire due elenchi collegati ordinati senza allocare memoria aggiuntiva, semplicemente attraversando entrambi gli elenchi e impostando i puntatori in modo appropriato. L'unione di due array normalmente richiederebbe almeno un array aggiuntivo.
Paul Tomblin,

1
Sì, la fusione delle liste è più efficiente in termini di memoria, ma non era proprio quello che stavo commentando. Dire che la fusione degli elenchi collegati sia O (1) è molto fuorviante senza chiarire il caso.
Herms,

Le liste di fusione di @Herms non sono più efficienti in termini di memoria rispetto alla fusione di matrici in qualsiasi modello di dati sensibile.
Alexei Averchenko,

2
Alexei Averchenko: è possibile concatenare due elenchi o persino unire due elenchi ordinati, con la memoria O (1). La concatenazione di due array richiede necessariamente la memoria O (n), a meno che gli array non siano già adiacenti nella memoria. Penso che il punto a cui stai mirando sia quello in cui un elenco di n elementi e un array di n elementi occupano entrambi memoria O (n), ma il coefficiente è più elevato per gli elenchi collegati.
rampion

17

Un argomento ampiamente non apprezzato per ArrayList e contro LinkedList è che i LinkedList sono scomodi durante il debug . Il tempo impiegato dagli sviluppatori di manutenzione per comprendere il programma, ad esempio per individuare bug, aumenti e IMHO a volte non giustifica i nanosecondi in miglioramenti delle prestazioni o byte nel consumo di memoria nelle applicazioni aziendali. A volte (beh, ovviamente dipende dal tipo di applicazioni), è meglio perdere qualche byte ma avere un'applicazione che è più gestibile o più facile da capire.

Ad esempio, in un ambiente Java e usando il debugger Eclipse, il debug di una ArrayList rivelerà una struttura molto facile da capire:

arrayList   ArrayList<String>
  elementData   Object[]
    [0] Object  "Foo"
    [1] Object  "Foo"
    [2] Object  "Foo"
    [3] Object  "Foo"
    [4] Object  "Foo"
    ...

D'altra parte, guardare il contenuto di una LinkedList e trovare oggetti specifici diventa un incubo facendo clic su Espandi-l'albero, per non parlare del sovraccarico cognitivo necessario per filtrare gli interni di LinkedList:

linkedList  LinkedList<String>
    header  LinkedList$Entry<E>
        element E
        next    LinkedList$Entry<E>
            element E   "Foo"
            next    LinkedList$Entry<E>
                element E   "Foo"
                next    LinkedList$Entry<E>
                    element E   "Foo"
                    next    LinkedList$Entry<E>
                    previous    LinkedList$Entry<E>
                    ...
                previous    LinkedList$Entry<E>
            previous    LinkedList$Entry<E>
        previous    LinkedList$Entry<E>

17

Prima di tutto, nelle liste collegate in C ++ non dovrebbe esserci molto più problema con cui lavorare rispetto a un array. È possibile utilizzare l' elenco std :: o l' elenco puntatore boost per gli elenchi collegati. I problemi chiave con gli elenchi collegati rispetto agli array sono lo spazio aggiuntivo necessario per i puntatori e il terribile accesso casuale. È necessario utilizzare un elenco collegato se

  • non è necessario un accesso casuale ai dati
  • aggiungerai / eliminerai elementi, specialmente in mezzo alla lista

14

Per me è così,

  1. Accesso

    • Gli elenchi collegati consentono solo l'accesso sequenziale agli elementi. Quindi la complessità algoritmica è l'ordine di O (n)
    • Le matrici consentono l'accesso casuale ai suoi elementi e quindi la complessità è dell'ordine di O (1)
  2. Conservazione

    • Gli elenchi collegati richiedono una memoria aggiuntiva per i riferimenti. Ciò li rende poco pratici per elenchi di piccoli elementi di dati come caratteri o valori booleani.
    • Le matrici non necessitano di spazio di archiviazione aggiuntivo per puntare all'elemento di dati successivo. È possibile accedere a ciascun elemento tramite indici.
  3. Taglia

    • La dimensione degli elenchi collegati è dinamica per natura.
    • La dimensione dell'array è limitata alla dichiarazione.
  4. Inserzione / delezione

    • Gli elementi possono essere inseriti ed eliminati in elenchi collegati a tempo indeterminato.
    • L'inserimento / cancellazione di valori negli array è molto costoso. Richiede la riallocazione della memoria.

Hai 2 numero 2 e 2 numero 3 :)
Hengameh,

Possiamo dichiarare un array vuoto e quindi continuare ad aggiungere dati come richiesto. Come fa ancora una dimensione fissa?
HebleV

11

Due cose:

La codifica di un elenco collegato è, senza dubbio, un po 'più impegnativa rispetto all'utilizzo di un array e si chiedeva cosa avrebbe giustificato lo sforzo aggiuntivo.

Non codificare mai un elenco collegato quando si utilizza C ++. Basta usare l'STL. Quanto sia difficile da implementare non dovrebbe mai essere un motivo per scegliere una struttura di dati piuttosto che un'altra perché la maggior parte è già implementata là fuori.

Per quanto riguarda le effettive differenze tra un array e un elenco collegato, la cosa importante per me è come pensi di utilizzare la struttura. Userò il termine vettore poiché è il termine per un array ridimensionabile in C ++.

L'indicizzazione in un elenco collegato è lenta perché è necessario attraversare l'elenco per raggiungere l'indice dato, mentre un vettore è contiguo in memoria e puoi arrivarci utilizzando la matematica del puntatore.

L'aggiunta alla fine o all'inizio di un elenco collegato è facile, poiché è necessario aggiornare solo un collegamento, in cui in un vettore potrebbe essere necessario ridimensionare e copiare il contenuto.

Rimuovere un elemento da un elenco è facile, poiché devi solo rompere una coppia di collegamenti e quindi ricollegarli. La rimozione di un oggetto da un vettore può essere più veloce o più lenta, a seconda se ti interessa l'ordine. Scambiare l'ultimo elemento sopra l'elemento che si desidera rimuovere è più veloce, mentre lo spostamento di tutto ciò che lo segue è più lento, ma mantiene l'ordine.


Come ho detto a qualcuno sopra, stavo solo cercando di mettere in relazione la domanda nel modo in cui mi è stata posta. Non userei mai un array (o un elenco di collegamenti roll-my-own) in C ++ - userò le versioni STL di entrambi.
Onorio Catenacci,

10

Eric Lippert ha recentemente pubblicato un post su uno dei motivi per cui gli array devono essere usati in modo conservativo.


2
Certamente un buon post, ma non pertinente in un elenco collegato rispetto alla discussione di array.
Robert Paulson,

2
Suggerirei che gran parte dell'articolo di Eric è rilevante, in quanto discute sia degli svantaggi delle matrici sia dei vantaggi degli Elenchi, indipendentemente dall'implementazione dell'elenco.
Bevan,

8

L'inserimento e la rimozione rapidi sono in effetti gli argomenti migliori per gli elenchi collegati. Se la tua struttura cresce in modo dinamico e non è necessario l'accesso a tempo costante a qualsiasi elemento (come stack e code dinamici), gli elenchi collegati sono una buona scelta.


7

Eccone uno veloce: la rimozione degli oggetti è più rapida.


7

Gli elenchi collegati sono particolarmente utili quando la raccolta è in costante crescita e riduzione. Ad esempio, è difficile immaginare di provare a implementare una coda (aggiungere alla fine, rimuovere dalla parte anteriore) usando un array: passeresti tutto il tempo a spostare le cose verso il basso. D'altra parte, è banale con una lista collegata.


4
Potresti avere una coda basata su array senza troppo lavoro che era ancora veloce / efficiente. Dovresti solo tenere traccia di quale indice era la "testa" e quale era la "coda". Funziona abbastanza bene se hai bisogno di una coda di dimensioni fisse (ad esempio, buffer di tastiera in un kernel).
Herms,

3
E si chiama "buffer circolare", se si desidera cercare nel riferimento dell'algoritmo preferito.
Steve Jessop,

7

Oltre ad aggiungere e rimuovere dal centro dell'elenco, mi piacciono di più gli elenchi collegati perché possono crescere e ridursi dinamicamente.


6
Anche i vettori (= sostanzialmente matrici) possono farlo e il costo ammortizzato per loro è solitamente più piccolo di quello per gli elenchi a causa di problemi di localizzazione di riferimento.
Konrad Rudolph,

7

Nessuno codifica più il proprio elenco di link. Sarebbe sciocco. La premessa che l'utilizzo di un elenco collegato richiede più codice è semplicemente errato.

In questi giorni, la creazione di un elenco collegato è solo un esercizio per gli studenti in modo che possano capire il concetto. Al contrario, tutti usano un elenco predefinito. In C ++, basato sulla descrizione nella nostra domanda, ciò significherebbe probabilmente un vettore stl (#include <vector> ).

Pertanto, la scelta di un elenco collegato rispetto a un array si basa esclusivamente sulla valutazione delle diverse caratteristiche di ciascuna struttura in relazione alle esigenze dell'app. Il superamento dell'onere di programmazione aggiuntivo dovrebbe avere un impatto zero sulla decisione.


2
Er..umm .. Lo std :: vector è un array, non un elenco collegato. L'elenco link standard è, beh, std :: list.
James Curran,

1
sì, ma penso che il vettore sia più vicino a ciò che l'op richiede, una sostituzione dinamica dell'array.
Joel Coehoorn,

@Joel, stavo solo cercando di mettere in relazione la domanda che mi è stata posta da quest'uomo che sta cercando di imparare il C ++. Non mi preoccuperei nemmeno di scrivere il mio elenco di link, ma è così che mi ha chiesto. :-)
Onorio Catenacci,

In ambienti con limiti di memoria (microcontrollori) per i quali sono presenti compilatori personalizzati, non viene implementato tutto il linguaggio (ad es. Contenitori in C ++). Quindi potrebbe essere che devi codificare il tuo elenco di link. nongnu.org/avr-libc/user-manual/FAQ.html#faq_cplusplus
Minh Tran

6

È davvero una questione di efficienza, l'overhead per inserire, rimuovere o spostare (dove non si sta semplicemente scambiando) elementi all'interno di un elenco collegato è minimo, ovvero l'operazione stessa è O (1), versi O (n) per un array. Ciò può fare una differenza significativa se si sta operando pesantemente su un elenco di dati. Hai scelto i tuoi tipi di dati in base a come opererai su di essi e scegli il più efficiente per l'algoritmo che stai utilizzando.


6

Le matrici hanno senso dove sarà noto il numero esatto di elementi e dove ha senso la ricerca per indice. Ad esempio, se volessi memorizzare lo stato esatto della mia uscita video in un determinato momento senza compressione, probabilmente utilizzerei un array di dimensioni [1024] [768]. Questo mi fornirà esattamente ciò di cui ho bisogno e un elenco sarebbe molto, molto più lento per ottenere il valore di un determinato pixel. Nei luoghi in cui un array non ha senso, in genere esistono tipi di dati migliori di un elenco per gestire i dati in modo efficace.


6

Array Vs Elenco collegato:

  1. L'allocazione della memoria dell'array a volte fallirà a causa della memoria frammentata.
  2. La memorizzazione nella cache è migliore negli array poiché a tutti gli elementi viene assegnato spazio di memoria contiguo.
  3. La codifica è più complessa delle matrici.
  4. Nessun limite di dimensione sull'elenco collegato, a differenza degli array
  5. L'inserimento / eliminazione è più rapido nell'elenco collegato e l'accesso è più veloce negli array.
  6. Elenco collegato meglio dal punto di vista multi-thread.

-1: tutti questi devono essere comprovati, non solo elencati.
John Saunders,

Ogni punto è già stato spiegato nelle risposte sopra. Essendo un ritardatario, non avevo altra scelta che elencare. A proposito, quale ti piacerebbe essere spiegato?
AKS,

Se sono già stati spiegati, allora perché rispondi?
John Saunders,

2
In modo che ti darà una visione sintetica della discussione. E mi piacciono questi tipi di risposte in modo da non dover leggere più volte la stessa spiegazione. E l'ho fatto per quelle persone che hanno lo stesso modo di pensare del mio. Ppl diversi hanno stili diversi. Niente di nuovo.
AKS,

3

poiché gli array sono di natura statica, quindi tutte le operazioni come l'allocazione della memoria avvengono solo al momento della compilazione. Quindi il processore deve dedicare meno sforzi al suo runtime.


3

Supponiamo di avere un set ordinato, che si desidera modificare anche aggiungendo e rimuovendo elementi. Inoltre, è necessaria la capacità di conservare un riferimento a un elemento in modo tale che in seguito sia possibile ottenere un elemento precedente o successivo. Ad esempio, un elenco di cose da fare o una serie di paragrafi in un libro.

Per prima cosa dovremmo notare che se si desidera conservare i riferimenti ad oggetti al di fuori dell'insieme stesso, probabilmente si finirà per archiviare i puntatori nella matrice, piuttosto che memorizzare gli oggetti stessi. Altrimenti non sarai in grado di inserire nell'array - se gli oggetti sono incorporati nell'array si sposteranno durante gli inserimenti e tutti i puntatori a essi diventeranno non validi. Lo stesso vale per gli indici di array.

Il tuo primo problema, come hai notato tu stesso, è l'inserimento - l'elenco collegato consente l'inserimento in O (1), ma un array generalmente richiede O (n). Questo problema può essere parzialmente risolto: è possibile creare una struttura di dati che offra un'interfaccia di accesso ordinaria simile a una matrice in cui sia la lettura che la scrittura sono, nella peggiore delle ipotesi, logaritmiche.

Il tuo secondo e più grave problema è che dato un elemento che trova l'elemento successivo è O (n). Se l'insieme non è stato modificato, è possibile mantenere l'indice dell'elemento come riferimento anziché come puntatore, rendendo in tal modo un'operazione successiva (O), ma poiché è tutto ciò che si ha è un puntatore all'oggetto stesso e in nessun modo per determinare il suo indice corrente nell'array diverso dalla scansione dell'intero "array". Questo è un problema insormontabile per gli array: anche se è possibile ottimizzare gli inserimenti, non è possibile fare nulla per ottimizzare l'operazione di ricerca del tipo successivo.


Potresti per favore elaborare questo: "è possibile creare una struttura di dati che offra un'interfaccia di accesso ordinale simile a un array in cui sia la lettura che la scrittura sono, nel peggiore dei casi, logaritmiche".
Hengameh,

1
Ci sono alcune cose su Wikipedia nella sezione Dynamic Array / Vriants. Non è proprio quello che avevo in mente, però ... Immagina un b + albero come una struttura con pagine ma senza chiavi, invece ogni pagina intermedia ricorda quanti elementi ci sono in ciascuna delle sottopagine, mentre le pagine foglia tengono semplicemente il elementi in un piccolo array. Quando si inserisce un elemento in una pagina foglia, è necessario spostare ~ metà pagina per fare spazio, quindi salire e aggiornare il conteggio degli elementi su tutte le pagine degli antenati. Quando cerchi un elemento # N, aggiungi semplicemente il conteggio degli elementi della pagina subordinata fino a quando non attraversi N, quindi scendi in quella sottostruttura
DenNukem

3

In un array hai il privilegio di accedere a qualsiasi elemento nel tempo O (1). Quindi è adatto per operazioni come la ricerca binaria Ordinamento rapido, ecc. L'elenco collegato d'altra parte è adatto per la cancellazione di inserimenti come nel tempo O (1). Entrambi hanno vantaggi e svantaggi e preferire l'uno all'altro si riduce a ciò che si desidera implementare.

- La domanda più grande è: possiamo avere un ibrido di entrambi. Qualcosa di simile a ciò che python e perl implementano come liste.


3

Lista collegata

È più preferibile quando si tratta di inserimento! Fondamentalmente ciò che fa è che si occupa del puntatore

1 -> 3 -> 4

Inserisci (2)

1 ........ 3 ...... 4
..... 2

Finalmente

1 -> 2 -> 3 -> 4

Una freccia dai 2 punti a 3 e la freccia da 1 punti a 2

Semplice!

Ma dall'array

| 1 | 3 | 4 |

Inserisci (2) | 1 | 3 | | 4 | | 1 | | 3 | 4 | | 1 | 2 | 3 | 4 |

Bene, chiunque può visualizzare la differenza! Solo per 4 indici stiamo eseguendo 3 passaggi

E se la lunghezza dell'array fosse un milione allora? L'array è efficiente? La risposta è no! :)

La stessa cosa vale per la cancellazione! In Elenco collegato possiamo semplicemente usare il puntatore e annullare l'elemento e successivamente nella classe di oggetti! Ma per l'array, dobbiamo eseguire shiftLeft ()

Spero che aiuti! :)


3

L'Elenco collegato è più un overhead da mantenere rispetto all'array, inoltre richiede una memoria aggiuntiva che tutti questi punti sono concordati. Ma ci sono alcune cose che array non può fare. In molti casi supponiamo che tu voglia un array di lunghezza 10 ^ 9 che non puoi ottenerlo perché deve trovarsi una posizione di memoria continua. Elenco collegato potrebbe essere un salvatore qui.

Supponiamo di voler archiviare più cose con i dati, in modo che possano essere facilmente estese nell'elenco collegato.

I contenitori STL di solito hanno un'implementazione dell'elenco collegato dietro la scena.


3

1- L' elenco collegato è una struttura di dati dinamica in modo che possa crescere e ridursi in fase di esecuzione allocando e deallocando la memoria. Quindi non è necessario fornire una dimensione iniziale dell'elenco collegato. L'inserimento e la cancellazione di nodi sono davvero più facili.

Le dimensioni 2- dell'elenco collegato possono aumentare o diminuire in fase di esecuzione, quindi non c'è spreco di memoria. Nel caso dell'array, c'è un sacco di spreco di memoria, come se dichiarassimo un array di dimensioni 10 e memorizzassimo solo 6 elementi, lo spazio di 4 elementi viene sprecato. Non esiste alcun problema nell'elenco collegato poiché la memoria viene allocata solo quando richiesto.

3- Strutture di dati come stack e code possono essere facilmente implementate utilizzando l'elenco collegato.


2

L'unico motivo per utilizzare l'elenco collegato è che inserire l'elemento è facile (rimuovendo anche).

Disadvatige potrebbe essere che i puntatori occupano molto spazio.

E su quel codice è più difficile: di solito non hai bisogno di un elenco di codici (o solo una volta) che sono inclusi in STL e non è così complicato se devi ancora farlo.


2
I puntatori occupano molto spazio? Non proprio. Se stai memorizzando un elenco collegato di booleani, sicuramente, in percentuale i puntatori occupano molto spazio. Ma se stai memorizzando oggetti complessi (che è generalmente il caso), i puntatori sarebbero probabilmente trascurabili.
Herms,

ho dimenticato il sorriso :) Ma ho detto "non potevo" non ".
user15453,

1

penso anche che l'elenco dei collegamenti sia più efficace degli array. perché attraversiamo nell'elenco dei collegamenti ma non negli array


1

A seconda della lingua, alcuni di questi svantaggi e vantaggi potrebbero essere considerati:

C Linguaggio di programmazione : quando si utilizza un elenco collegato (in genere tramite puntatori a struttura), è necessario prestare particolare attenzione a non perdere la memoria. Come accennato in precedenza, gli elenchi collegati sono facili da mescolare, perché tutto ciò che stava facendo è cambiare i puntatori, ma ricorderemo di liberare tutto?

Java : Java ha un garbage collection automatico, quindi la perdita di memoria non sarà un problema, ma nascosti dal programmatore di alto livello sono i dettagli di implementazione di ciò che è un elenco collegato. Metodi come la rimozione di un nodo dal centro dell'elenco sono più complicati di una procedura di quanto alcuni utenti della lingua si aspetterebbero.


1

Perché un elenco collegato su un array? Come alcuni hanno già detto, maggiore velocità di inserzioni ed eliminazioni.

Ma forse non dobbiamo vivere con i limiti di nessuno dei due e ottenere il meglio da entrambi, allo stesso tempo ... eh?

Per le eliminazioni di array, è possibile utilizzare un byte "Eliminato", per rappresentare il fatto che una riga è stata eliminata, pertanto non è più necessario riprogrammare l'array. Per alleviare l'onere degli inserimenti o la rapida modifica dei dati, utilizzare un elenco collegato per quello. Quindi, quando ti riferisci a loro, fai prima cercare la tua logica, poi l'altra. Quindi, usarli in combinazione ti dà il meglio di entrambi.

Se si dispone di un array davvero grande, è possibile combinarlo con un altro array o elenco collegato molto più piccolo in cui quello più piccolo contiene 20, 50, 100 elementi utilizzati più di recente. Se quello necessario non si trova nell'elenco o nell'array collegato più breve, si passa all'array di grandi dimensioni. Se trovato lì, puoi quindi aggiungerlo all'elenco / array collegato più piccolo presumendo che "le cose usate più di recente sono più simili a riutilizzare" (e sì, probabilmente eliminando dall'elenco l'elenco degli elementi utilizzati più di recente). Il che è vero in molti casi e risolto un problema che ho dovuto affrontare in un modulo di controllo delle autorizzazioni di sicurezza .ASP, con facilità, eleganza e velocità impressionante.


1

Mentre molti di voi hanno toccato i principali vantaggi / dislivelli dell'elenco collegato rispetto all'array, la maggior parte dei confronti riguarda il modo in cui uno è migliore / peggiore dell'altro. è possibile eseguire l'accesso casuale in array ma non è possibile nell'elenco collegato e altri. Tuttavia, ciò presuppone che gli elenchi di collegamenti e l'array verranno applicati in un'applicazione simile. Tuttavia, una risposta corretta dovrebbe essere come l'elenco di collegamenti sarebbe preferito sull'array e viceversa in una particolare distribuzione dell'applicazione. Supponiamo che tu voglia implementare un'applicazione per dizionari, cosa useresti? Matrice: mmm consentirebbe un facile recupero attraverso la ricerca binaria e altri algoritmi di ricerca .. ma lasciamo pensare a come l'elenco dei collegamenti può essere migliore..Sicuro che si desidera cercare "BLOB" nel dizionario. Avrebbe senso avere un elenco di collegamenti di A-> B-> C-> D ---->

A -> B -> C -> ...Z
|    |    |
|    |    [Cat, Cave]
|    [Banana, Blob]
[Adam, Apple]

Ora l'approccio sopra è migliore o una matrice piatta di [Adam, Apple, Banana, Blob, Cat, Cave]? Sarebbe possibile anche con l'array? Quindi un grande vantaggio dell'elenco dei collegamenti è che puoi avere un elemento che non punta solo all'elemento successivo ma anche a qualche altro elenco di collegamenti / array / heap / o qualsiasi altra posizione di memoria. L'array è una memoria contigua piatta suddivisa in blocchi di dimensioni dell'elemento che sta per memorizzare. L'elenco dei collegamenti d'altra parte è un gruppo di unità di memoria non contigue (può essere di qualsiasi dimensione e contenere qualsiasi cosa) e puntare a ciascuna altro come vuoi tu. Allo stesso modo diciamo che stai creando un'unità USB. Ora desideri che i file vengano salvati come array o come elenco di collegamenti? Penso che tu abbia l'idea di cosa sto indicando :)

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.