Classe 42/A - Giovanni Novelli Fondamenti di Informatica Prof. Cantone MODULO Strutture dati...
-
Upload
bettino-molinari -
Category
Documents
-
view
217 -
download
0
Transcript of Classe 42/A - Giovanni Novelli Fondamenti di Informatica Prof. Cantone MODULO Strutture dati...
Classe 42/A - Giovanni Novelli
Fondamenti di Informatica
Prof. Cantone
MODULO
“Strutture dati avanzate e allocazione dinamica della
memoria”
Modulo 2 – IV Anno
MODULO 2: “Strutture dati avanzate e allocazione dinamica della memoria ”
• UD3: “Le liste” ( 4 sett.)
• UD4: “Pile e code” ( 2 sett.)
• UD5: “Alberi e Grafi” ( 1 sett.)
tot. 7 settimane(42 ore)
Per modulo 2
Modulo 2 – IV Anno
MODULO 2: “Strutture dati avanzate e allocazione dinamica della memoria ”
Questo modulo è proposto per una quarta classe di un Istituto Tecnico Industriale ad indirizzo Informatico.
L’obiettivo del modulo è di presentare:• schemi significativi di organizzazione delle informazioni;• le regole operative per la manipolazione delle strutture astratte di dati;• i metodi di rappresentazione (memorizzazione) delle strutture dati dinamiche all’interno di un elaboratore.
Unità Didattica 3: Le liste
INTRODUZIONE
• Prerequisiti
• Competenze
• Descrittori
• Metodologie, Spazi e Strumenti
• Verifiche e Valutazione
• Tempi
Prerequisiti
Conoscenza della rappresentazione della memoria in un calcolatore
Conoscenze sicure del linguaggio C++ Uso delle strutture di controllo, delle strutture
dati e delle funzioni Definizione delle classi con attributi e metodi Applicazione dei concetti di programmazione
ad oggetti nel linguaggio C++
Competenze
Comprendere la differenza tra gestione statica e gestione dinamica della memoria
Individuare soluzioni dei problemi basate sull’uso di liste di dati dinamiche
Definire i modelli di classe
Descrittori
Conoscenze:• Creazione dinamica di aree di memoria
• Implementazione di liste
• Modelli di classe
Descrittori
Abilità:• Saper scrivere un programma che usa la
gestione della memoria utilizzando liste dinamiche semplici
• Saper scrivere un programma che usa la gestione della memoria utilizzando liste dinamiche doppie
Metodologie
Lezione frontale Lezione dialogata Brainstorming
Spazi
Aula Laboratorio
Strumenti
Libro di testo Dispense Lavagna Computer
Verifiche
Questionari e test (strutturati e semi-strutturati)
Esercitazioni di laboratorio Presentazione dei risultati delle
esercitazioni in aula Colloqui individuali
Valutazione
Impegno Attenzione Conoscenze Competenze Abilità
Tempi
12 ore di lezione 6 ore di laboratorio 3 ore di verifica 3 ore di recupero e/o potenziamento
UD1: Le liste
Gestione statica e gestione dinamica della memoria
Liste semplici Liste doppie
Gestione della memoria
Statica• Il numero massimo di elementi di un vettore è
definito a tempo di compilazione (compile time) e allocato all’avviamento del codice eseguibile
Dinamica• Vengono definite aree di memoria disponibili
per l’allocazione/deallocazione a tempo di esecuzione (run time)
Implementazione statica di liste Un esempio di lista implementata staticamente è un
vettore di 500 elementi per la memorizzazione del numero di tessera dei clienti che parcheggiano la propria automobile nell’autorimessa
In questo tipo di problema è noto il numero di automobili che l’autorimessa è in grado di ospitare
Ci sono situazioni in cui il numero massimo di elementi non è noto a priori
L’allocazione di vettori di dimensione abbastanza ampia per contenere il valore massimo possibile di elementi è di per sé inefficiente in quanto generalmente comporta un oneroso dispendio di memoria
Gestione dinamica della memoria in C++
Le istruzioni per l’allocazione della memoria vengono richiamate durante l’esecuzione del programma
Il C++ dispone delle istruzioni new (allocazione di nuova memoria) e delete (deallocazione della memoria).
Allocazione di nuova memoria in C++
L’istruzione new deve essere seguita dal tipo di dato di cui si vuole allocare la memoria
Tale istruzione restituisce l’indirizzo di memoria
E’ importante assegnare il risultato ad un puntatore per evitare la creazione di memoria garbage
Deallocazione di memoria in C++
L’istruzione delete è seguita dall’indirizzo di memoria da deallocare, solitamente contenuto in un puntatore.
E’ buona norma utilizzare tale istruzione per deallocare la memoria non più utilizzata per renderla disponibile al programma o ad altri programmi onde evitare anche il possibile esaurimento della risorsa (memory leak)
Esempio di utilizzo delle istruzioni new e delete (1/2)#include <iostream.h>
void main()
{
int *p = new int; // allocazione di un intero
*p = 10;
cout << *p << endl;
delete p; // deallocazione
p = new int[3]; //allocazione dinamica di un array di interi
p[0] = p[2] = 4;
p[1] = 5;
cout << *p++ << “ “<< *p++ << “ “<< *p++ << endl;
delete (p-3);
}
Esempio di utilizzo delle istruzioni new e delete (2/2) L’esecuzione del programma produce il
seguente output:104 5 4
Alcuni compilatori liberano la memoria dinamica prima della chiusura del programma ma è buona norma deallocare tutte le variabili allocate dinamicamente in modo da evitare l’insorgere di memory leaks.
Definizione di lista
Una lista è una sequenza di elementi di un determinato tipo
è un multinsieme ovvero vi possono essere ripetizioni del medesimo elemento
è una sequenza (collezione ordinata) ovvero siamo in grado di individuare il primo elemento, il secondo, etc...
Le liste e la memoria
Realizzazione come vettore di N elementi non adeguata quando non è noto a priori il massimo numero di elementi della lista (allocazione statica della memoria)
Rappresentazione collegata (linked lists) mediante puntatori (allocazione dinamica della memoria)
Liste: rappresentazione linked
Si memorizzano gli elementi associando a ciascuno di essi l’informazione (riferimento) che permette di individuare la locazione in cui è inserito l’elemento successivo
Si possono realizzare mediante strutture dati dinamiche
Notazione grafica
testa
a b c
Elementi della lista come nodi e riferimenti come archi.
[‘a’,’b’,’c’]
Operazioni
Inserimento in testa Eliminazione in testa Inserimento di un elemento Eliminazione di un elemento
Inserimento in testa
testa
a b c
L = [‘a’,’b’,’c’] L = [‘f’,‘a’,’b’,’c’]
f
Eliminazione in testa
testa
a b c
L = [‘a’,’b’,’c’] L = [’b’,’c’]
Inserimento di un elemento
testa
a b d
L = [‘a’,’b’,’d’] L = [‘a’,’b’,’c’,’d’]
c
Eliminazione di un elemento
testa
a b c
L = [‘a’,’b’,’c’] L = [’a’,’c’]
Implementazione in C++ di una lista semplice
definizione della struttura dati implementazione delle operazioni di:
• inserimento di un elemento in testa
• eliminazione di un elemento
Codifica C++ - Dichiarazione tipo
typedef char Info;
typedef struct Cella {
Info value;
struct Cella *next;
} Cella;
value next
Classe Listaclass Lista { Cella *cima, *coda;public:
Lista() : cima(0), coda(0) {} // costruttore~Lista() { // distruttore
Cella *cella = cima;while (cella) { cima = cella->next; delete cella;
cella = cima;}
}
Classe Lista: Inserimento in testa
void insert(Info info) { // inserisce la info in testa
Cella *cella = new Cella;
cella->value = info;
cella->next = cima;
cima = cella;
}
Classe Lista: Eliminazione di un elementoint remove(Info info) { // rimuove la info dalla lista
Cella *cella = cima;Cella *prev = NULL;while (cima) { cima = cella->next; if (cella->value == info) { // va rimossa la cella
if (prev) { prev->next = cima; }
delete cella; return 0;
} prev = cella;}
return 1;}
Liste: doubly linked(1/3)
Si memorizzano gli elementi associando a ciascuno di essi le informazioni (riferimenti) che permettono di individuare le locazioni in cui sono inseriti l’elemento precedente e quello successivo
Si possono realizzare mediante strutture dati dinamiche
Liste: doubly linked(2/3)
Una doubly linked list può immaganizzare informazioni di qualunque tipo.
L’implementazione in C++ che verrà illustrata nelle slide che seguono è relativa alla memorizzazione di stringhe.
Liste: doubly linked(3/3)
Tutte le doubly linked lists condividono due operazioni fondamentali:• inserimento di un elemento nella lista
• rimozione di un elemento dalla lista L’implementazione presentata di seguito
fornisce ulteriori operazioni quali:• ricerca di un elemento
• modifica di un elemento
• overloading degli operatori << e >> per le operazioni di I/O
Notazione grafica
Elementi della lista come nodi e riferimenti come archi.
[‘a’,’b’,’c’]
a b c
Operazioni
Inserimento in coda Eliminazione di un elemento per valore Visualizzazione della lista dall’inizio Visualizzazione della lista dalla fine Ricerca di un elemento per valore
Classe dblinkDichiarazione (1/3)const int STRSIZE = 80;class dblink { char info[STRSIZE]; // informazione
dblink *next; // puntatore all’elemento successivodblink *prior; // puntatore all’elemento precedente
public:dblink() { // costruttore lista vuota next = NULL; prior = NULL;};dblink(char *s) { // costruttore lista con un elemento
if (strlen(s)<STRSIZE) strcpy(info,s);else *info = NULL;next = NULL;prior = NULL;
}
Classe dblinkDichiarazione (2/3)void store(dblink **start, dblink **end); // inserimento di un elementovoid remove(dblink **start, dblink **end); // eliminazione void frwdlist(); // visualizzazione
dall’iniziovoid bkwdlist(); // visualizzazione dalla
fine
dblink *getnext() {return next;}dblink *getprior() {return prior;}
int change(char *s); // modifica di un elementovoid getinfo(char *s) {strcpy(s, info);}dblink *find(char *s); // ricerca di un elemento
Classe dblinkDichiarazione (3/3)// Overloading di << per l’oggetto di tipo dblink friend ostream &operator<<(ostream &stream, dblink o){
stream << o.info << “\n”;return stream;
}// Overloading di << per il puntatore all’oggetto di tipo dblinkfriend ostream &operator<<(ostream &stream, dblink *o){
stream << o->info << “\n”;return stream;
}// Overloading di >> per i riferimenti ad oggetti di tipo dblinkfriend istream &operator>>(istream &stream, dblink &o){
stream >> o.info;return stream;
}
Classe dblink La variabile info contiene l’informazione memorizzata in
ciascuna cella della lista Questo esempio di classe è stato progettato per la
gestione di liste doppie di stringhe Lo stesso tipo generale di meccanismo può essere
utilizzato per mantenere liste con qualsiasi tipo di informazione
Quando si vogliono implementare metodi che tengano conto dell’ordine tra le informazioni va definito un metodo per confrontare gli elementi fra di loro. Ciò è facilmente realizzabile utilizzando l’overloading degli operatori di confronto
Classe dblinkInserimento in coda (1/3)
void dblink::store(dblink **start, dblink **end) { // inserimento in coda
if (*start==NULL) { //inserimento all’inizio della lista se è vuota
next = NULL;
prior = NULL;
*end = *start = this;
}
else { // inserimento in coda
next = NULL;
prior = *end;
(*end)->next = this;
*end = this;
}
}
Inserimento in coda
L = [‘a’,’b’] L = [‘a’,’b’,’c’]
a b c
Classe dblinkInserimento in coda (2/3) Questo metodo fa sì che l’oggetto puntato da o sia aggiunto
alla fine della lista. Al metodo vengono passati gli indirizzi dei puntatori all’inizio e
alla fine della lista. Questi puntatori sono già stati creati altrove all’interno del
programma che usa la classe. I puntatori start e end devono essere posti a NULL quando il
programma inizia. Quando il primo elemento viene aggiunto alla lista, start e end
puntano ad esso Ciascun successivo inserimento causa l’aggiornamento di end. In questo modo start e end puntano sempre rispettivamente
all’inizio e alla fine della lista.
Classe dblinkInserimento in coda (3/3) Il seguente frammento di codice mostra come dichiarare i puntatori
start e end e come aggiungere oggetti alla lista.
dblink a(“One”), b(“Two”), c(“Three”);dblink *start, *end;
end = start = NULL;
a.store(&start, &end);b.store(&start, &end);c.store(&start, &end);
Questa implementazione dell’inserimento fa sì che la lista non sia ordinata. Il metodo store può essere modificato per mantenere la lista ordinata.
Classe dblinkEliminazione di un elemento (1/2)
void dblink::remove(dblink **start, dblink **end) { // eliminazione
if (prior) {
prior->next = next;
if (next) next->prior = prior;
else *end = prior;
}
else {
if (next) {
next->prior = NULL;
*start = next;
}
else *start = *end = NULL;
}
}
Classe dblinkEliminazione di un elemento (2/2) Questo metodo fa sì che l’oggetto puntato da o sia rimosso
dalla lista. Un elemento della lista può trovarsi in testa, in coda o nel
mezzo. Il metodo considera tutti e tre i casi. Il metodo va chiamato con gli indirizzi dei puntatori a start e end
come parametri. Esempio di chiamata al metodo per un oggetto ob nella lista:
• ob.remove(&start,&end); Il metodo rimuove un elemento dalla lista ma non distrugge il
relativo oggetto, lo scollega semplicemente. Sia il metodo remove che il metodo store nell’attuale
implementazione sono indipendenti dal tipo di informazione memorizzata nella lista.
Esercizi
Realizzare le seguenti funzioni da aggiungere alla classe dblink:
Funzione Scopogetfirst() Restituisce un puntatore al primo elemento
getlast() Restituisce un puntatore all’ultimo elemento
getlength() Restituisce il numero di elementi della lista
Classe 42/A - Giovanni Novelli