Docente: Giuseppe Scollo
Università di Catania, sede di Comiso (RG)
Facoltà di Scienze Matematiche, Fisiche e Naturali
Corso di Studi in Informatica applicata, AA 2006-7
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++:
struct node { Elem elem; node *next; }; typedef node *nlink;
link
per il tipo del puntatore al nodo, per evitare conflitti
con l'uso di tale nome nella libreria standard
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:
nlink p = new node ;
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:
p->elem, p->next
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:
struct node { Elem elem; node *next; node(Elem e, node *n) { elem = e; next = n; }; }; typedef node *nlink;
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
nlink p = new node(a, t) ;
prestazioni di operazioni su lista (concatenata) e array (contiguo):
inserimento
di un nodo in una lista concatenata:
t->next = x->next; x->next = t;
t
dopo il nodo x
rimozione
di un nodo da una lista concatenata:
x->next = x->next->next;
x
t = x->next; x->next = t->next;
delete t;
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
#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 }
main
; ideare un programma equivalente che effettui la
suddetta costruzione eseguendo solo due istruzioni di assegnamento
a puntatore per ogni nuovo nodo