Una lista concatenata offre alcuni vantaggi rispetto agli array
Una lista non ha una dimensione massima, quindi non si ha spreco di spazio inutilizzato o, viceversa, non succede che un elemento non trova posto perché si è esaurito lo spazio. Inoltre in una lista gli elementi possono essere inseriti o eliminati senza alterare la posizione degli altri elementi.
Una lista si definisce concatenata perché ogni elemento contiene il puntatore al successivo elemento. Si supponga che gli elementi contenuti nella lista siano di tipo intero. I metodi di una classe Lista sono:
| Metodo | Operazione | Parametro ricevuto | Parametro restituito |
| Lista () | costruttore senza parametri | void | void |
| Lista | costruttore copia | Lista | void |
| ~Lista | distruttore | void | void |
| Inserisci() | Inserisce un elemento in testa alla lista | Tipo dell'elemento di lista | |
| NumeroElementi() | Restituisce il numero degli elementi contenuti nella lista | void | int |
| Svuota() | Elimina tutti gli elementi contenuti nella lista | void | void |
| Elimina() | Elimina il primo elemento della lista, se contenuto, che è uguale a quello specificato | Tipo dell'elemento di lista | void |
| Stampa() | Stampa tutti gli elementi contenuti nella lista | void | void |
| Ricerca() | Indica se un dato elemento è, contenuto nella lista | Tipo dell'elemento di lista | bool |
| Nr. linea | Commento |
| 4-7 | Si definisce la struttura Record: contiene un campo dato e un campo puntatore al successivo. |
| 8, 9, 10 | Il costruttore assegna i valori iniziali a campi della classe. |
| Nr. linea | Commento |
| 12 | Lista(const Lista& lst) Il costruttore Copia riceve il riferimento ad una lista, che non viene modificata (const): L'oggetto lst ricevuto come parametro: ![]() |
| 13 | if ((this != &lst) && primo) Se il riferimento ricevuto (lst) non punta alla stessa lista e la lista lst contiene almeno un elemento (primo diverso da 0) si procede con la copia della lista lst in questa lista. |
| 14 | primo = new Record Si crea un nuovo record e si raccoglie il suo puntatore nel campo primo della classe ![]() |
| 15 | primo->dato = lst.primo->dato Nella sezione dato del nuovo record si copia il valore contenuto nel corrispondente elemento della lista da copiare ![]() |
| 16 | PRec lp = lst.primo Si crea un nuovo puntatore a Record e lo si inizializza con il puntatore al primo Record della lista da copiare. ![]() |
| 17 | PRec p = primo p è un puntatore a Record inizializzato con il puntatore al primo Record della lista in cui copiare gli elementi. ![]() |
| 18 | while (lp->successivo Si avanza nella lista da copiare, fintanto che non si raggiunge il puntatore 0 |
| 19 | p->successivo = new Record Si aggiunge un nuovo record alla lista in cui copiare il nodo dalla lista sorgente lst. Il puntatore al nuovo nodo viene scritto nel campo succesivo del record puntato da p |
| 20 | p = p->successivo Si passa al nodo successivo. ![]() |
| 21, 22 | lp = lp->successivo p->dato = lp->dato Si avanza nella lista sorgente e si copia il campo dalla lista sorgente alla lista destinazione. ![]() |
| 24 | p->successivo = 0 Quando si raggiunge la fine della lista sorgente si assegna il valore 0 anche al puntatore contenuto nell'ultimo record della lista, per indicare la fine della lista. |
| Nr. linea | Commento |
| 30 | Inserisci(const Elemento& el) Il metodo Inserisci riceve il riferimento ad un intero, che non viene modificato (const): |
| 31 | PRec p = new Record Viene creato un nuovo nodo e il puntatore viene mamorizzato in p |
| 32 | p->dato = el nel canpo dato del nuovo nodo viene memorizzato il valore ricevuto come parametro. |
| Nr. linea | Commento |
| 38 | PRec p = primo Si dichiara un puntatore locale alla struttura Record e lo si inizializza con il puntatore alla testa della Lista. |
| 39 | while (p) { si entra in un ciclo che si ripete se p è diverso da 0. |
| 40 | cout << p->dato << " - " si stampa il valore contenuto nel campo dato del nodo. |
| 41 | p = p->successivo si avanza nella lista, leggendo il puntatore al nodo successivo e assegnandone il valore al puntatore p. |
| 42 | si ritorna al test di ripetizione del ciclo while |
| Nr. linea | Commento |
| 45 | Il metodo NumeroElementi restituisce il numero di elementi contenuti nella Lista. |
| Nr. linea | Commento |
| 48 | PRec cancella si dichiara un puntatore a Record. |
| 49 | while (primo) { si entra in un ciclo a condizione che il puntatore al primo elemento della lista sia diverso da 0. |
| 50 | cancella = primo si effettua una copia del puntatore al primo elemento della lista. |
| 51 | primo = primo->successivo il successivo elemento diventa il nuovo elemento di testa della lista, eliminando così dalla lista il primo elemento che è puntato dal puntatore cancella. |
| 52 | delete cancella si elimina lo spazio occupato dal nodo estratto dalla lista. |
| 54 | conteggio = 0 Al termine del ciclo il campo membro conteggio viene posto a 0. |
| Nr. linea | Commento |
| 56 | Elimina(const Elemento& el) { il metodo riceve come parametro il riferimento a un intero, che rappresenta il valore che si vuole eliminare dalla lista. |
| 57 | if(primo) { se la lista non è vuota. |
| 58 | if (primo->dato == el) { se il primo elemento della lista conteine il valore ricevuto come parametro. |
| 59 | PRec cancella = primo si salva il puntatore al primo elemento della lista. |
| 60 | primo->successivo si passa al successivo elemento. |
| 61 | delete cancella si elimina lo spazio occupato dal nodo. |
| 62 | conteggio-- si conta un elemento in meno. |
| 63 | altrimenti si entra in un ciclo di scansione della lista, alla ricerca del nodo il cui campo dato sia uguale al parametro el |
| Nr. linea | Commento |
| 79 | bool Ricerca(const Elemento& el) { il metodo riceve come parametro il riferimento a un intero, che rappresenta il valore che si vuole eliminare dalla lista e restituisce un valore booleano. |
| 80 | PRec p = primo Si accede alla lista. |
| 81 | bool trovato = false si crea una variabile booleana. |
| 82 | while ((p) && (!trovato)) { Si scandisce la lista, a condizione che l'elemento non sia stato trovato e non si sia raggiunta la fine della lista. |
| 83, 84 | if (p->dato ==el) trovato = true Se il nodo raggiunto contiene il valore cercato si ritorna true. |
| 86 | p = p->successivo altrimenti si avanza nella lista. |
| Nr. linea | Commento |
| 5 | La funzione StampaMenu()verrà richiamato
per proporre le possibili operazioni ammesse sulla lista. |
| Nr. linea | Commento |
| 19, 20 | vengono dichiarate due variabili |
| 21 | Lista lista viene dichiarata l'istanza lista della classeLista |
| 21 | |
| 22 | do { Si entra in un ciclo |
| 23 | StampaMenu() viene richiamata la funzione per mostrare il menu |
| 24 | cin >> i la scelta avviene introducendo un numero da tastiera e premendo invio. Il tasto premuto viene acquisito in formato carattere |
| 25 | switch(c) { a seconda del carattere il flusso del programma subisce una diramazione verso l'operazione scelta |
| 56, 61 | Si deve notare che (linea 57) viene creata una seconda istanza della classe Lista richiamando il costruttore copia (quello con un parametro di ingresso). Le operazioni sono inserite in un blocco in modo che al termine dell'uso della lista copiata venga richiamato il distruttore. |
linea