Lista
1️⃣ Descrizione

Una lista è una struttura dati che organizza una collezione di elementi in una sequenza ordinata. Le liste sono ampiamente utilizzate in programmazione per memorizzare dati in modo dinamico e flessibile.
Esistono diversi tipi di liste, tra cui:
- Lista Collegata: Una lista collegata è una sequenza di nodi, ognuno dei quali contiene un elemento di dati e un riferimento al successivo nodo nella sequenza. La lista inizia con un nodo chiamato "testa", e il suo ultimo nodo ha il suo riferimento impostato a
null
. Le operazioni di inserimento e rimozione in una lista collegata sono efficienti, specialmente all'inizio o alla fine della lista.
- Lista Concatenata: Una lista concatenata è simile a una lista collegata, ma offre funzionalità aggiuntive come l'accesso casuale agli elementi tramite l'indicizzazione. Ogni elemento della lista contiene anche un riferimento al precedente nodo, consentendo un accesso efficiente a qualsiasi posizione della lista.
- Lista Doppiamente Collegata: È una variante della lista collegata in cui ogni nodo ha un riferimento sia al nodo precedente che a quello successivo nella sequenza. Questo consente un accesso bidirezionale agli elementi della lista, rendendo più efficienti alcune operazioni come l'eliminazione di elementi.
- Lista Circolare: In una lista circolare, l'ultimo nodo della lista punta al primo nodo anziché a
null
, creando un ciclo continuo. Questo permette di attraversare la lista senza fine.
Le liste forniscono una flessibilità notevole perché possono crescere e contrarsi dinamicamente durante l'esecuzione del programma. Possono anche contenere elementi di diversi tipi di dati e possono essere facilmente estese con nuove operazioni o funzionalità.
Le liste sono ampiamente utilizzate per implementare una varietà di strutture dati complesse, come pile, code, alberi e grafi, e sono fondamentali in molte aree della programmazione, inclusi algoritmi, strutture dati e applicazioni di database.
2️⃣ Implementazione
Classe Nodo
La classe Nodo
rappresenta un elemento fondamentale di una lista collegata. Ogni nodo contiene due parti principali:
- Info(
info
): Questo è il contenuto effettivo del nodo. È il valore che il nodo memorizza o rappresenta.
- Link (
link
): Questo è un riferimento al prossimo nodo nella lista. Ogni nodo, tranne l'ultimo, punta al nodo successivo. L'ultimo nodo della lista ha il suo link impostato sunull
, indicando la fine della lista.
Inoltre, la classe Nodo
fornisce metodi per accedere e modificare questi attributi:
getInfo()
: Restituisce il valore memorizzato nel nodo.
getLink()
: Restituisce il riferimento al nodo successivo.
setLink(Nodo link)
: Imposta il riferimento al nodo successivo.
public class Nodo {
private int info; // valore del nodo corrente
private Nodo link; // puntatore al nodo successivo
public Nodo(int info) {
this.info = info;
this.link = null; // non ha ancora un nodo successivo
}
public int getInfo() {
return info;
}
public Nodo getLink() {
return link;
}
public void setLink(Nodo link) {
this.link = link; // setto il nodo successivo
}
public void setInfo(int info) {
this.info = info;
}
}
Classe Lista
La classe Lista
rappresenta una sequenza di nodi collegati. Contiene due parti principali:
- Testa (
head
): Questo è un riferimento al primo nodo della lista. Se la lista è vuota,head
sarànull
. Ogni operazione sulla lista inizia dalla testa.
- Dimensione (
dimensione
): Questo tiene traccia del numero di elementi presenti nella lista. È utile per ottenere rapidamente la dimensione della lista senza dover attraversare tutti i nodi.
La classe Lista
offre metodi per manipolare la lista collegata:
- Costruttore: Inizializza una lista vuota.
getDimensione()
: Restituisce il numero di elementi nella lista.
VisitaLista()
: Stampa tutti gli elementi presenti nella lista, scorrendo dahead
fino anull
.
InserisciInTesta(int dato)
: Aggiunge un nuovo nodo all'inizio della lista. Questo metodo crea un nuovo nodo con il dato specificato e lo collega alla testa della lista, rendendolo il nuovo primo nodo.
InserisciInCoda(int dato)
: Aggiunge un nuovo nodo alla fine della lista. Questo metodo scorre la lista fino all'ultimo nodo e collega il nuovo nodo alla sua fine.
EliminaInTesta()
: Rimuove il primo nodo dalla lista. Questo metodo aggiorna la testa della lista per puntare al secondo nodo, eliminando così il primo nodo.
EliminaInCoda()
: Rimuove l'ultimo nodo dalla lista. Questo metodo scorre la lista fino al penultimo nodo e lo collega anull
, eliminando così l'ultimo nodo.
Insieme, la classe Nodo
e la classe Lista
forniscono un'implementazione di una lista collegata, una struttura dati dinamica in cui gli elementi sono collegati da nodi e possono essere aggiunti o rimossi in modo efficiente.
public class Lista {
private Nodo head; // punta al primo elemento della lista (null se vuota)
private int dimensione; // numero di elementi nella lista
public Lista() {
this.head = null;
this.dimensione = 0;
}
// restituisce la dimensione della lista
public int getDimensione() {
return dimensione;
}
// stampa
public void VisitaLista() {
Nodo p = head;
// itero fino a trovare l'ultimo elemento della lista
while (p != null) {
System.out.print(p.getInfo() + " ");
p = p.getLink();
}
}
public void InserisciInTesta(int dato) {
Nodo n = new Nodo(dato); // nuovo nodo
n.setLink(head); // Il link del nuovo nodo punta al nodo corrente (head)
head = n; // Il nuovo nodo diventa la nuova testa della lista
dimensione++;
}
public void InserisciInCoda(int dato) {
Nodo n = new Nodo(dato); // nuovo nodo
if (head == null) { // caso in cui la lista e' vuota
head = n;
} else {
Nodo p = head; // Nodo al primo elemento della lista
while (p.getLink() != null) {
p = p.getLink();
}
n.setLink(null);
p.setLink(n);
}
dimensione++;
}
public void InserisciInMezzo(int dato, int posizione) {
if (posizione < 0 || posizione > dimensione)
throw new IllegalArgumentException("Errore: Posizione non valida");
Nodo n = new Nodo(dato); // nuovo nodo
if (posizione == 0) {
// inserimento in testa
n.setLink(head);
head = n;
} else {
Nodo p = head;
for (int i = 0; i < posizione-1; i++) {
p = p.getLink();
}
n.setLink(p.getLink());
p.setLink(n);
}
dimensione++;
}
public void EliminaInTesta() {
// se la lista e' vuota non posso eliminare nulla
if (head == null)
return;
head = head.getLink();
dimensione--;
}
public void EliminaInCoda() {
if (head == null)
return;
if (head.getLink() == null) { // caso in cui la lista contiene un solo elemento
head = null;
} else {
Nodo p = head; // nodo di testa
// p.getList() -> nodo i; p.getLink().getLink() -> nodo i+1
while (p.getLink().getLink() != null) {
p = p.getLink();
}
p.setLink(null);
}
dimensione--;
}
public void EliminaInMezzo(int posizione) {
if (posizione < 0 || posizione > dimensione)
throw new IllegalArgumentException("Errore: Posizione non valida");
if (head == null)
throw new IllegalStateException("Errore: Lista gia' vuota");
if (posizione == 0) {
// elimina in testa
head = head.getLink();
} else {
Nodo p = head;
for (int i = 0; i < posizione - 1; i++) {
p = p.getLink();
}
p.setLink(p.getLink().getLink());
}
dimensione--;
}
}
public class Main {
public static void main(String[] args) {
// Creazione di una nuova lista
Lista lista = new Lista();
// Inserimento di alcuni elementi
lista.InserisciInCoda(10);
lista.InserisciInCoda(20);
lista.InserisciInCoda(30);
// Stampa della lista
System.out.println("Lista dopo l'inserimento:");
lista.VisitaLista();
// Eliminazione in testa
lista.EliminaInTesta();
System.out.println("\nLista dopo l'eliminazione in testa:");
lista.VisitaLista();
// Eliminazione in coda
lista.EliminaInCoda();
System.out.println("\nLista dopo l'eliminazione in coda:");
lista.VisitaLista();
// Inserimento in testa
lista.InserisciInTesta(40);
System.out.println("Lista dopo l'inserimento in testa:");
lista.VisitaLista();
// Inserimento in mezzo
lista.InserisciInMezzo(25, 1);
System.out.println("Lista dopo l'inserimento in mezzo:");
lista.VisitaLista();
// Eliminazione in mezzo
lista.EliminaInMezzo(1);
System.out.println("Lista dopo l'eliminazione in mezzo:");
lista.VisitaLista();
}
}