Liste semplici (semplicemente linkate) Una lista semplice e costituita da nodi Laboratorio di Informatica 7. Strutture complesse di dati in C++ Ogni nodo e una struttura che contiene : Dati Un riferimento (puntatore) al nodo successivo Riferimenti esterni Puntatore al primo elemento della lista: Un riferimento speciale indica la fine della lista: Puntatore a Puntatore al nodo stesso Corso di Laurea in Ingegneria Elettronica e Telecomunicazioni A.A. 2013-2014 2 Semestre Prof. Giovanni Pascoschi 2 Liste semplici Esempio lista semplice Struttura logica di una lista semplice Il terminatore è un puntatore a 0xBA04 0xBA42 0xBB86 0xBA04 125 0xBA42 453 0xBB86 627 Il terminatore è un puntatore all'elemento stesso struct node { int data; node* next; ; In una lista circolare il terminatore punta al primo elemento della lista 3 4
Esempio lista semplice Esempio lista semplice : inserimento Una lista semplice può essere percorsa solo in avanti, cioè dalla testa verso la coda Per scorrere una lista è necessaria una variabile temporanea per puntare ad un generico elemento Non si può usare il puntatore alla testa altrimenti si perde il riferimento al primo elemento Per inserire un nuovo elemento nella lista bisogna trovare la posizione giusta e poi aggiustare i puntatori. prec puntatore corrente puntatore alla testa della lista = ; // punta alla testa della lista = ->next; // punta al prossimo nodo della lista struct node* nuovo; nuovo = new node; nuovo->data = 1234; nuovo->next = ; nuovo nuovo->next = ; prec->next = nuovo; 5 6 Esempio lista semplice : cancellazione Esempio Lista semplice (in ordine alfabetico) Per cancellare un nuovo elemento nella lista bisogna trovare la posizione giusta e poi aggiustare i puntatori. prec struct node* ; = prec->next; prec->next = ->next; 7 #include <iostream> #include <string> using namespace std; struct Node{ string nome; Node* next; ; Node* ; void StartupList( ); // creazione lista vuota void ResetList( ); // eliminazione lista void InsertList( ); //inserimento nuovo nodo void RemoveList( ); //cancellazione nodo void ShowList(); // visualizza lista bool IsEmptyList(); // lista vuota? void menu( ); int main( ) { int scelta; StartupList( ); do { do { menu( ); cout<< Seleziona una voce ; cin>>scelta; while(scelta <1 scelta >5); switch(scelta) { case 1: InsertList( ); case 2: RemoveList( ); case 3: ShowList( ); case 4: ResetList( ); while(scelta!=5); ResetList(); return 0; 8
Esempio Lista semplice Esempio Lista semplice void StartupList( ) { =; bool IsEmptyList( ) { if (== ) return true; else return false; void ShowList( ) { Node* v; cout<< Elenco dei nominativi <<endl; v = ; while(v!= ) { cout<< v->nome << endl; v = v->next; cout<< Fine elenco nominativi <<endl; void ResetList( ) { Node* ; while(!= ) { cout<< Nominativo eliminato: << ->nome << endl; = ; = -> next; delete ; cout<< Lista vuota <<endl; void menu( ) { cout << endl; cout << 1. Inserisci nominativo << endl; cout << 2. Rimuovi nominativo << endl; cout << 3. Visualizza lista << endl; cout << 4. Svuota lista << endl; cout << 5. Fine << endl; void InsertList( ) { string Nomeins; Node* nuovo; // puntatore del nuovo nodo Node* ; // puntatore temporaneo Node* prec; // puntatore al nodo precedente cout<< Nominativo da inserire ; //info nuovo nodo cin>> Nomeins; nuovo = new Node; nuovo-> nome = Nomeins; nuovo->next = ; if(isemptylist()==true) = nuovo; // se lista vuota nuovo = nuova testa if(->nome >= nuovo->nome) { //nuovo nodo precede testa in ord. alf? = ; // la testa diventa il nodo = nuovo; // il nuovo nodo diventa la testa ->next = ; //il puntatore al next di testa è return; 9 10 Esempio Lista semplice Esempio Lista semplice = ; //nodo fluttuante temporaneo while(!= && nuovo->nome>=->nome) { // si scorre la lista fino alla fine prec = ; // il nodo temporaneo diventa il nodo precedente = ->next; // il puntatore al successivo viene assegnato a temp nuovo->next = ; // si è trovato il nodo che segue il nodo nuovo prec->next = nuovo; void RemoveList( ) { string Nomeins; Node* ; // puntatore temporaneo Node* prec; // puntatore al nodo precedente bool trovato = false; cout<< Nominativo da rimuovere ; cin>> Nomeins; if(isemptylist()==true) cout<< La lista è già vuota <<endl; // lista vuota if(->nome == Nomeins) { //nome = nome inserito? trovato = true; // la testa diventa il nodo = ->next; // il nuovo nodo diventa la testa : si salva next cout<< Nome eliminato: << ->nome <<endl; delete ; = ; // nuova testa è l elemento successivo 11 12
Esempio Lista semplice Lista doppiamente linkata = ->next; //nodo fluttuante temporaneo prec = ; while(!trovato &&!= ) { // si scorre la lista fino alla fine if(->nome == Nomeins) { trovato = true; prec->next = ->next; // il nodo viene bypassato cout<< Nome eliminato : << ->nome << endl; delete ; prec = ; // diventa il nodo precedente = ->next; // ->next diventa in nuovo if(! trovato) cout<< Nome non trovato nella lista <<endl;; Una lista doppiamente linkata e costituita da nodi Ogni nodo e una struttura che contiene Dati Un riferimento (puntatore) al nodo successivo Un riferimento (puntatore) al nodo precedente Riferimenti esterni Puntatore al primo elemento della lista: Puntatore al primo elemento della lista in senso opposto: Un riferimento speciale indica la fine della lista in maniera analoga alle liste semplici 13 14 Liste doppiamente linkate Esempio lista doppiamenta linkata Struttura logica di una lista doppiamente linkata I terminatori sono due puntatori a Struttura logica di una lista doppiamente linkata non circolare e i terminatori puntatori a I terminatori sono due puntatori all elemento stesso 0xBA04 0xBA04 0xBAF4 0xBB32 0xBAF4 0xBB32 345 2156 201 0xBA04 0xBAF4 0xBB32 In una lista circolare i terminatori puntano al capo opposto della lista struct node { int data; struct node* next; struct node* prev; ; 15 16
Esempio lista doppiamenta linkata Esempio lista doppia : inserimento Una lista doppia può essere percorsa in due versi: In avanti, cioè dalla testa verso la coda Indietro, cioè dalla coda verso la testa È necessaria una variabile temporanea per puntare ad un generico elemento Per inserire un nuovo elemento nella lista bisogna trovare la posizione giusta e poi aggiustare i puntatori. = ; = ->next; // per scorrere in avanti la lista = ; = ->prev; // per scorrere all indietro la lista 17 18 Esempio lista doppia : inserimento Esempio lista doppia : rimozione struct node* nuovo; nuovo = new node; Per rimuovere un nodo da una lista doppiamente linkata bisogna trovare la posizione giusta e poi aggiustare i puntatori. nuovo->data = 1234; nuovo->next = ; nuovo->prev = ; old nuovo->next = ->next; nuovo->prev = ; ->next->prev = nuovo; ->next = nuovo; 19 20
Esempio lista doppia : rimozione Riepilogo della lezione struct node* old; old = ->next; ->next=old->next; old->next->prev=old->prev; delete old; Liste linkate semplici Liste doppiamente linkate Strutture complesse di dati old 21 22 Fine della lezione Domande? 23