Upload
others
View
8
Download
0
Embed Size (px)
Citation preview
Orario delle lezioniOrario delle lezioni
martedì
15.00 - 18.00
LABORATORIO
lab Turing
Strutture Dati
mercoledì
16.00 – 18.00
TEORIA
aula P/4
Libro di testoLibro di testo
Data Structures & Algorithms in Java
Michael T. Goodrich Roberto Tamassia
John Wiley & Sons, Inc.(quarta edizione)
Strutture Dati
Sito del corsoSito del corso
Strutture Dati
http://www.dia.unisa.it/professori/demarco/sd/
Esercitazioni integrativeEsercitazioni integrative
Strutture Dati
Dal 23 marzo:
Corso integrativo di esercitazione
Prof. Rosalba Zizza
Venerdì dalle 9.00 alle 12.00Laboratorio Reti
Strutture dati e tipi astratti di datiStrutture dati e tipi astratti di dati
Informazione organizzataallo scopo di migliorare l'efficienza
dell'algoritmo
Definisce con rigore matematico una struttura dati
Struttura dati implementata
Programma
Algoritmo Struttura dati
Tipo astratto di dati
Strutture Dati
La struttura dati pila (stack)La struttura dati pila (stack)
Inserimento, cancellazione e ricerca avvengono solo in una posizione
viene cancellato sempre l'oggetto che è stato inserito per ultimo
inserimento e cancellazione avvengono secondo una strategia LIFO (last in first out):
inserimento:un nuovo oggetto viene inserito in cima allo stack
cancellazione:viene cancellato sempre l'oggetto in cima allo stack
Strutture Dati
Il tipo astratto di dati (ADT) stackIl tipo astratto di dati (ADT) stackTipo di dati e operazioniTipo di dati e operazioni
Dati: oggetti arbitrari (stringhe, interi, pezzi di codice, ...)
Operazioni: - push (element): inserisce un elemento
- element pop(): restituisce l'elemento inserito per ultimo e lo rimuove
- element top(): restituisce l'elemento in cima
- integer size(): restituisce il numero di elementi presenti
- boolean isEmpty(): è vero se e solo se non ci sono elementi
Strutture Dati
Un esempioUn esempio
Operazione Operazione OutputOutput
Strutture Dati
Un esempioUn esempio
Operazione Operazione OutputOutput
5
—push(5)
Strutture Dati
Un esempioUn esempio
Operazione Operazione OutputOutput
5
push(8)
—
—
push(5)
Strutture Dati
8
Un esempioUn esempio
Operazione Operazione OutputOutput
push(8)
pop()
—
—
8
push(5)
Strutture Dati
5
Un esempioUn esempio
Operazione Operazione OutputOutput
push(8)
pop()
—
—
8
push(5)
Strutture Dati
5
3
push(3) —
Un esempioUn esempio
Operazione Operazione OutputOutput
push(8)
pop()
—
—
8
push(5)
Strutture Dati
5
push(3) —
pop() 3
Un esempioUn esempio
Operazione Operazione OutputOutput
push(8)
pop()
—
—
8
push(5)
Strutture Dati
push(3) —
pop() 3
pop() 5
Un esempioUn esempio
Operazione Operazione OutputOutput
push(8)
pop()
—
—
8
push(5)
Strutture Dati
push(3) —
pop() 3
pop() 5
pop() ?
EccezioniEccezioni
Qual è il risultato di un'operazione di pop() (o di top()) su uno stack vuoto?
Il tipo astratto di dati (ADT) stackIl tipo astratto di dati (ADT) stack
Strutture Dati
EccezioniEccezioni
Una exception si verifica quando un'operazione non può essere eseguita.
Ad esempio:
- top() su uno stack vuoto
- pop() su uno stack vuoto
Il tipo astratto di dati (ADT) stackIl tipo astratto di dati (ADT) stack
Strutture Dati
Qual è il risultato di un'operazione di pop() (o di top()) su uno stack vuoto?Qual è il risultato di un'operazione di pop() (o di top()) su uno stack vuoto?
ApplicazioniApplicazioni
Ogni volta che viene visitato un nuovo sito, l'indirizzo del sito corrente viene inserito nello stack con un'operazione di push.
Cronologia pagine visitate con un navigatore webCronologia pagine visitate con un navigatore web
Strutture Dati
Ogni volta che viene visitato un nuovo sito, l'indirizzo del sito corrente viene inserito nello stack con un'operazione di push.
Strutture Dati
ApplicazioniApplicazioniCronologia pagine visitate con un navigatore webCronologia pagine visitate con un navigatore web
In cima allo stack ci sarà sempre l'indirizzo dell'ultima pagina visitata
La proprietà LIFO dello stack ci garantisce che il tasto back ci farà visualizzare le pagine in ordine cronologico inverso (dalla più recente alla più vecchia)
Ogni volta che viene visitato un nuovo sito, l'indirizzo del sito corrente viene inserito nello stack con un'operazione di push.
Strutture Dati
ApplicazioniApplicazioniCronologia pagine visitate con un navigatore webCronologia pagine visitate con un navigatore web
Ogni volta che viene visitato un nuovo sito, l'indirizzo del sito corrente viene inserito nello stack con un'operazione di push.
La pressione del tasto "back" del navigatore genera un'operazione di pop dello stack.
In cima allo stack ci sarà sempre l'indirizzo dell'ultima pagina visitata
La proprietà LIFO dello stack ci garantisce che il tasto back ci farà visualizzare le pagine in ordine cronologico inverso (dalla più recente alla più vecchia)
Strutture Dati
ApplicazioniApplicazioniCronologia pagine visitate con un navigatore webCronologia pagine visitate con un navigatore web
Ogni volta che viene visitato un nuovo sito, l'indirizzo del sito corrente viene inserito nello stack con un'operazione di push.
La pressione del tasto "back" del navigatore genera un'operazione di pop dello stack.
Strutture Dati
ApplicazioniApplicazioniCronologia pagine visitate con un navigatore webCronologia pagine visitate con un navigatore web
Implementazione stackImplementazione stackUna semplice soluzione con arrayUna semplice soluzione con array
. . .
top
0 1 2 t
Siccome quando si crea un array è necessario definire la sua taglia (size), l'implementazione dello stack mediante array comporta la specifica della massima taglia N dello stack.
N-1
Lo stack viene implementato con un array di N elementi e una variabile t che indica l'indice dell'elemento in cima allo stack
Strutture Dati
Implementazione stack con arrayImplementazione stack con array
Algorithm size():return t + 1
Pseudocodice dei metodiPseudocodice dei metodi
. . .
top
0 1 2 t N-1
Strutture Dati
Algorithm isEmpty():return (t < 0)
. . .
top
0 1 2 t N-1
Strutture Dati
Implementazione stack con arrayImplementazione stack con arrayPseudocodice dei metodiPseudocodice dei metodi
Algorithm top():if isEmpty() then
throw a EmptyStackExceptionreturn S[t]
. . .
top
0 1 2 t N-1
Strutture Dati
Implementazione stack con arrayImplementazione stack con arrayPseudocodice dei metodiPseudocodice dei metodi
Algorithm push(element):if size() = N then throw a FullStackExceptiont := t + 1S[t] := element
. . .
top
0 1 2 t N-1
Strutture Dati
Implementazione stack con arrayImplementazione stack con arrayPseudocodice dei metodiPseudocodice dei metodi
Implementazione stack con arrayImplementazione stack con arrayVantaggi e svantaggiVantaggi e svantaggi
Vantaggi Implemetazione semplice ed efficiente Memoria usata: O(N) Complessità dei metodi (size, isEmpty, top, push, pop): O(1)
Svantaggi Bisogna fissare a priori un limite superiore N alla massima taglia dello stack
Un'applicazione potrebbe richiedere una capacità
superiore ad N
Un'applicazione potrebbe richiedere una capacità molto
inferiore ad N
Lo Stack lancia una StackFullException che arresta
l'applicazione
Spreco di memoria
Strutture Dati
inserimento e cancellazione avvengono secondo una strategia FIFO (first in first out):
inserimento:un nuovo oggetto viene inserito dietro la coda
cancellazione:viene cancellato sempre l'oggetto davanti alla coda
La struttura dati coda (queue)La struttura dati coda (queue)
in
outviene cancellato sempre l'oggetto che è stato inserito per primo
Inserimento, cancellazione e ricerca avvengono solo in due posizioni
Strutture Dati
Il tipo astratto di dati coda (queue)Il tipo astratto di dati coda (queue)
Dati: oggetti arbitrari
Operazioni: - void enqueue (element): inserisce un nuovo elemento dietro (rear) la coda
- element dequeue(): restituisce l'elemento in testa (front) alla coda (quello che è stato più a lungo in coda) e lo rimuove
- element front(): restituisce l'elemento in testa alla coda
- integer size(): restituisce il numero di elementi presenti in coda
- boolean isEmpty(): è vero se e solo se non ci sono elementi in coda
Tipo di dati e operazioniTipo di dati e operazioni
Strutture Dati
Il tipo astratto di dati coda (queue)Il tipo astratto di dati coda (queue)
Operazione Operazione OutputOutput
Un esempio Un esempio
—enqueue(5)
Strutture Dati
5
Il tipo astratto di dati coda (queue)Il tipo astratto di dati coda (queue)
Operazione Operazione OutputOutput
enqueue(8)
Un esempio Un esempio
—
—
enqueue(5)
Strutture Dati
58
Il tipo astratto di dati coda (queue)Il tipo astratto di dati coda (queue)
Operazione Operazione OutputOutput
enqueue(8)
dequeue()
Un esempio Un esempio
—
—
5
enqueue(5)
Strutture Dati
8
Il tipo astratto di dati coda (queue)Il tipo astratto di dati coda (queue)
Operazione Operazione OutputOutput
enqueue(8)
dequeue()
enqueue(6)
Un esempio Un esempio
—
—
5
—
enqueue(5)
Strutture Dati
86
Il tipo astratto di dati coda (queue)Il tipo astratto di dati coda (queue)
Operazione Operazione OutputOutput
enqueue(8)
dequeue()
enqueue(6)
Un esempio Un esempio
dequeue()
—
—
5
—
8
enqueue(5)
Strutture Dati
6
Il tipo astratto di dati coda (queue)Il tipo astratto di dati coda (queue)
Operazione Operazione OutputOutput
enqueue(8)
dequeue()
enqueue(6)
Un esempio Un esempio
dequeue()
—
—
5
—
8
enqueue(5)
Strutture Dati
dequeue() 6
Il tipo astratto di dati coda (queue)Il tipo astratto di dati coda (queue)
Operazione Operazione OutputOutput
enqueue(8)
dequeue()
enqueue(6)
Un esempio Un esempio
dequeue()
—
—
5
—
8
enqueue(5)
Strutture Dati
dequeue() 6
dequeue() error
Ricordare: una exception si verifica quando un'operazione non può essere eseguita.
Ad esempio:
- front() su una coda vuota
- dequeue() su una coda vuota
Le eccezioni Le eccezioni Il tipo astratto di dati coda (queue)Il tipo astratto di dati coda (queue)
Strutture Dati
Implementazione codaImplementazione coda
. . .
0 21 N-1
Come tenere traccia di front e rear della coda?
front rear
Una semplice soluzione con array Una semplice soluzione con array
- Q[0] contiene la testa della coda (front)- inseriamo gli oggetti da sinistra a destra - una variabile rear indica la prima cella libera
Strutture Dati
. . .
0 21 N-1
Come tenere traccia di front e rear della coda?
front rear
- Q[0] contiene la testa della coda (front)- inseriamo gli oggetti da sinistra a destra - una variabile rear indica la prima cella libera
Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array
Strutture Dati
. . .
0 21 N-1
Come tenere traccia di front e rear della coda?
front rear
- Q[0] contiene la testa della coda (front)- inseriamo gli oggetti da sinistra a destra - una variabile rear indica la prima cella libera
Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array
Strutture Dati
. . .
0 21 N-1
Come tenere traccia di front e rear della coda?
front rear
- Q[0] contiene la testa della coda (front)- inseriamo gli oggetti da sinistra a destra - una variabile rear indica la prima cella libera
Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array
Strutture Dati
. . .
0 21 N-1
Come tenere traccia di front e rear della coda?
front rear
- Q[0] contiene la testa della coda (front)- inseriamo gli oggetti da sinistra a destra - una variabile rear indica la prima cella libera
Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array
Strutture Dati
. . .
0 21 N-1
Come tenere traccia di front e rear della coda?
front rear
- Q[0] contiene la testa della coda (front)- inseriamo gli oggetti da sinistra a destra - una variabile rear indica la prima cella libera
Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array
Strutture Dati
. . .
0 21 N-1
Come tenere traccia di front e rear della coda?
front rear
- Q[0] contiene la testa della coda (front)- inseriamo gli oggetti da sinistra a destra - una variabile rear indica la prima cella libera
Problema: come fare dequeue?
Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array
Strutture Dati
. . .
0 21 N-1
Come tenere traccia di front e rear della coda?
front rear
- Q[0] contiene la testa della coda (front)- inseriamo gli oggetti da sinistra a destra - una variabile rear indica la prima cella libera
Questa soluzione non è efficiente perché in caso di dequeue si dovranno spostare tutti i rimanenti oggetti di una posizione a sinistra:
ciò richiede complessità O(n), dove n è il numero di oggetti in coda
Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array Implementazione codaImplementazione codaUna semplice soluzione con array Una semplice soluzione con array
Strutture Dati
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
. . .
All'inizio f = r = 0 (la coda è vuota)
f = r = 0
0 21 N-1
- quando aggiungiamo un elemento, basterà incrementare r fino alla prossima cella disponibile
- quando cancelliamo un elemento, basterà spostare f alla cella successiva
Definiamo due variabili f e r :
Strutture Dati
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
. . .
f
0 21 N-1
- quando aggiungiamo un elemento, basterà incrementare r fino alla prossima cella disponibile
- quando cancelliamo un elemento, basterà spostare f alla cella successiva
r
Strutture Dati
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
. . .
f
0 21 N-1
- quando aggiungiamo un elemento, basterà incrementare r fino alla prossima cella disponibile
- quando cancelliamo un elemento, basterà spostare f alla cella successiva
r
Strutture Dati
. . .
f
0 21 N-1
- quando aggiungiamo un elemento, basterà incrementare r fino alla prossima cella disponibile
- quando cancelliamo un elemento, basterà spostare f alla cella successiva
r
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
Strutture Dati
. . .
f
0 21 N-1
- quando aggiungiamo un elemento, basterà incrementare r fino alla prossima cella disponibile
- quando cancelliamo un elemento, basterà spostare f alla cella successiva
r
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
Strutture Dati
. . .
f
0 21 N-1
- quando aggiungiamo un elemento, basterà incrementare r fino alla prossima cella disponibile
- quando cancelliamo un elemento, basterà spostare f alla cella successiva
r
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
Strutture Dati
. . .
Ora f = r (la coda è vuota)
0 21 N-1
- quando aggiungiamo un elemento, basterà incrementare r fino alla prossima cella disponibile
- quando cancelliamo un elemento, basterà spostare f alla cella successiva
f = r
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
Strutture Dati
. . .0 21 N-1
In generale:
se la coda è vuota:
f = r
se la coda non è vuota:
- f è l'indice della cella che contiene il primo elemento della coda (front)
- r è l'indice della cella dove verrà inserito il prossimo elemento della coda
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
Strutture Dati
. . .0 21 N-1
La coda è vuota ma lo spazio a disposizione sull'array è finito
Inconveniente n. 1
Situazione dopo una serie di N enqueue e dequeue consecutive:
f = r = N - 1
Se ora volessimo inserire un elemento nella coda, dovremmo incrementare r , ma ciò non è permesso perché r ha già raggiunto il limite massimo consentito dalla taglia dell'array
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
Strutture Dati
Incremento di f: f = ( f + 1) mod N
Incremento di r: r = ( r + 1) mod N
f = r = N - 1
Per evitare il problema f ed r possono essere incrementati "circolarmente"
quando f = r la coda è vuota
. . .0 21 N-1
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
Strutture Dati
. . .0 21 N-1
Questa condizione corrisponde alla situazione di coda vuota!
Inconveniente n. 2
Situazione dopo una successione di N enqueue consecutive:
f = r
Si può ovviare ponendo a N - 1 il limite massimo di oggetti che la coda può contenere
Implementazione codaImplementazione codaUn'altra soluzione con array (più efficiente) Un'altra soluzione con array (più efficiente)
Strutture Dati
Implementazione coda con arrayImplementazione coda con arrayPseudocodice dei metodiPseudocodice dei metodi
. . .
Algorithm size(): return (N + r - f) mod N
fr
0 21 N-1
. . .
f
0 21 N-1
r
Strutture Dati
Implementazione coda con arrayImplementazione coda con arrayPseudocodice dei metodiPseudocodice dei metodi
. . .0 21 N-1
Algorithm isEmpty(): return (f = r)
f r
Strutture Dati
Implementazione coda con arrayImplementazione coda con arrayPseudocodice dei metodiPseudocodice dei metodi
Algorithm front(): if isEmpty() then throw a EmptyQueueException return Q[f]
. . .0 21 N-1
f r
Strutture Dati
Implementazione coda con arrayImplementazione coda con arrayPseudocodice dei metodiPseudocodice dei metodi
Algorithm dequeue(): if isEmpty() then throw a EmptyQueueException temp := Q[f] Q[f] := null f := (f+1) mod N return temp
. . .0 21 N-1
f r
Strutture Dati
Implementazione coda con arrayImplementazione coda con arrayPseudocodice dei metodiPseudocodice dei metodi
Algorithm enqueue(element) if size() = N - 1 then throw a FullQueueException Q[r ] := element r := (r + 1) mod N
. . .0 21 N-1
f r
Strutture Dati
Implementazione coda con arrayImplementazione coda con arrayVantaggi e svantaggiVantaggi e svantaggi
Vantaggi Implemetazione semplice ed efficiente Memoria usata: O(N) Complessità dei metodi (size, isEmpty, front, enqueue, dequeue): O(1)
Svantaggi Bisogna fissare a priori un limite superiore N alla massima taglia della coda
Strutture Dati