Orario delle lezioni...Libro di testo Data Structures & Algorithms in Java Michael T. Goodrich...

Post on 22-Aug-2021

5 views 0 download

transcript

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