Logo dell'Università di Catania: Siciliae Studium Generale 1434 Logo del Centro IPPARI, Programmazione
matite e gomma
Loghi istituzionali: Siciliae Studium Generale 1434, Centro ricerche IPPARI, Università di Catania, Facoltà di Scienze Matematiche, Fisiche, Naturali, Insegnamento di Programmazione

Liste concatenate

Lezione 8 di Programmazione 2

Docente: Giuseppe Scollo

Università di Catania, sede di Comiso (RG)
Facoltà di Scienze Matematiche, Fisiche e Naturali
Corso di Studi in Informatica applicata, AA 2007-8

Logo di Conformità WCAG-1 di Livello Tripla A, W3C-WAI Web Content Accessibility Guidelines 1.0 Validazione XHTML 1.0 Validazione CSS 2

Indice

  1. Liste concatenate
  2. struttura di una lista concatenata
  3. allocazione di memoria e inizializzazione
  4. operazioni su liste, rilascio della memoria
  5. esempio: il problema di Giuseppe Flavio
  6. il problema di Giuseppe Flavio in C++
  7. esercizi

struttura di una lista concatenata

lista: struttura dati omogenea ad accesso sequenziale

lista concatenata: costituita da un insieme di nodi, ciascuno dei quali contiene:

la lista è rappresentata da un puntatore che dà accesso al suo primo nodo

rappresentazione elementare in C++:

allocazione di memoria e inizializzazione

con la definizione elementare della struttura della lista data sopra, l'allocazione di memoria per un nodo fa uso dell'operatore new, che restituisce un puntatore al nodo creato:

l'inizializzazione del nodo si effettua quindi con l'assegnamento di valori ai suoi membri (p*).elem e (p*).next; questi si possono designare con una notazione più confortevole:

si possono combinare allocazione di memoria e inizializzazione di un nuovo nodo se nella definizione si include un'operazione costruttore, omonima al tipo della struttura:

questa definizione fornisce anche l'implementazione del costruttore, che inizializza i membri della struttura con i valori dei parametri; ad esempio, per creare un nodo inizializzandone i membri ai valori a, t, e ottenere in p il puntatore al nuovo nodo già inizializzato, basta invocare

operazioni su liste, rilascio della memoria

prestazioni di operazioni su lista (concatenata) e array (contiguo):

inserimento di un nodo in una lista concatenata:   t->next = x->next; x->next = t;

rimozione di un nodo da una lista concatenata:     x->next = x->next->next;

esempio: il problema di Giuseppe Flavio

il puntatore nell'ultimo nodo di una lista può essere nullo, oppure puntare allo stesso nodo, o al primo nodo:

le liste circolari hanno diverse applicazioni, ne vediamo una in un algoritmo per il problema di Giuseppe Flavio, usabile ad es. quale meccanismo di selezione di un leader in un gruppo:

il problema consiste nel prevedere chi sarà il superstite finale, dati N, M e la posizione di inizio del conteggio selettivo

il problema di Giuseppe Flavio in C++

#include <iostream>
#include <cstdlib>
using namespace std;
struct node
{ int elem; node* next;
  node(int e, node* t) { elem = e; next = t; };
};
typedef node* nlink;
int main(int argc, char *argv[])
{ int i, N = atoi(argv[1]), M = atoi(argv[2]);
  nlink t = new node(1, 0); t->next = t;    // creazione lista circolare di 1 nodo
  nlink x = t;
  for (i = 2; i <= N; i++)
    x = (x->next = new node(i, t));         // inserimento i-esimo nodo nella lista
  while (x != x->next)
  {                                         // finché il nodo non punta a sé stesso:
    for (i = 1; i < M; i++) x = x->next;    // scorrimento di M-1 nodi
    x->next = x->next->next;                // rimozione M-simo nodo
  }
  cout << x->elem << endl;                  // output del superstite
}

esercizi

  1. modificare il programma qui proposto per il problema di Giuseppe Flavio, in modo da produrre in output i valori degli elementi della lista, nell'ordine definito dalla stessa, prima dell'inizio di ogni ciclo che conduce alla rimozione di un nodo
  2. quando costruisce la lista, il programma qui proposto per il problema di Giuseppe Flavio esegue tre istruzioni di assegnamento a puntatore per ogni nuovo nodo della lista: una nel costruttore e due nel main; ideare un programma equivalente che effettui la suddetta costruzione eseguendo solo due istruzioni di assegnamento a puntatore per ogni nuovo nodo
  3. eseguire l'esercizio 1 sul programma ideato nell'esercizio 2 e verificare l'equivalenza del programma così prodotto e di quello prodotto nell'esercizio 1