Home Insegnanti Contattami Portfolio

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:

  1. 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.
  1. 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.
  1. 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.
  1. 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:

  1. Info(info): Questo è il contenuto effettivo del nodo. È il valore che il nodo memorizza o rappresenta.
  1. 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 su null, indicando la fine della lista.

Inoltre, la classe Nodo fornisce metodi per accedere e modificare questi attributi:

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:

  1. Testa (head): Questo è un riferimento al primo nodo della lista. Se la lista è vuota, head sarà null. Ogni operazione sulla lista inizia dalla testa.
  1. 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:

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();
    }
}