Pile e code Laboratorio di Algoritmi 02/03 Prof. Ugo de’ Liguoro AlgoLab - Pile e Code Pile: definizione informale Una pila è una struttura dati lineare, cui gli elementi possono essere aggiunti o sottratti da un solo estremo (LIFO). AlgoLab - Pile e Code Operazioni sulle pile Una pila (stack) si definisce astrattamente come una struttura dati su cui siano definite alemeno quattro operazioni: 1. 2. 3. 4. Push(e,s) : aggiunge e alla pila s Pop(s) : elimina l’elemento emergente da s Top(s) : ritorna il valore dell’emergente di s IsEmpty(s): ritorna true se s non ha elementi. Nota: se s è vuota, Pop(s) e Top(s) sono indefinite. AlgoLab - Pile e Code L’interfaccia Stack interface Stack { void push(Object newitem); // aggiunge newitem come emergente void pop(); // rimuove l’emergente dalla pila Object top(); // ritorna l’emergente senza rimuoverlo boolean empty(); // true se la pila e’ vuota } AlgoLab - Pile e Code L’interfaccia List interface List { void cons (Object newitem); // aggiunge newitem in testa alla lista boolean insert(Object newitem, int index); // inserisce newitem alla pos. index; false // se index > length() boolean delete(int index); // rimuove l’elemento di pos. index; false se // index not in 0..length()-1 Object retrieve(int index); // pre: index in 0..length()-1 // post: ritorna l’elemento di indice index public int length (); // ritorna la lunghezza } AlgoLab - Pile e Code Le pile implementate come liste Supponendo di aver riscritto SList in modo tale che implementi l’interfaccia List, e quindi sia generica (elementi di tipo Object): class StackByList extends SList implements Stack { public void push(Object newitem) {cons(newitem);} public void pop() {delete(0);} public Object top() {return retrieve(0);} public boolean empty() {return length() == 0;} } AlgoLab - Pile e Code La gerarchia dei tipi e delle classi L’implementazione delle pile presentata si basa dunque sulla gerarchia (interfacce e relazioni di implementazione in rosso, classi e relazioni di ereditarietà in blu): List Stack SList StackByList AlgoLab - Pile e Code Notazione polacca postfissa Nella notazione polacca postfissa per le espressioni aritmetiche un operatore segue i suoi operandi. E’ definita dalla grammatica: <espressione> ::= <numerale> | <espressione> <espressione> <operatore> Esempi: (7 + 3) £ 5 7 + 3£5 si traduce in si traduce in 7 3+5£ 7 35£+ AlgoLab - Pile e Code Algoritmo di valutazione Valuta (Stringa espr) // espr è fatta di parole separate da spazi s := pila vuota while (scansione di espr non è finita) e := prossima parola di espr; if (e è un numerale) then Push(e,s) else // e è un operatore n := Top(s); Pop(s); // l’ordine di lettura ed eliminaz. m := Top(s); Pop(s); // dalla coda è importante … op := oppure a seconda di e; Push(m op n, s) // … qui return Top(s). // se espr è un’espr. in not. polacca, s ha un solo el. AlgoLab - Pile e Code Esecuzione dell’algoritmo 4 8 7 3 + top 4 AlgoLab - Pile e Code Esecuzione dell’algoritmo 4 8 7 3 + top 8 4 AlgoLab - Pile e Code Esecuzione dell’algoritmo 4 8 7 3 + top 7 8 4 AlgoLab - Pile e Code Esecuzione dell’algoritmo 4 8 7 3 + top 3 7 8 4 AlgoLab - Pile e Code Esecuzione dell’algoritmo 4 8 7 3 + top 10 8 4 AlgoLab - Pile e Code Esecuzione dell’algoritmo 4 8 7 3 + top 80 4 AlgoLab - Pile e Code Esecuzione dell’algoritmo 4 8 7 3 + top 2 80 4 AlgoLab - Pile e Code Esecuzione dell’algoritmo 4 8 7 3 + top 40 4 AlgoLab - Pile e Code Esecuzione dell’algoritmo 4 8 7 3 + top 44 AlgoLab - Pile e Code Code: definizione informale Le code sono strutture lineari i cui elementi si inseriscono da un estremo e si estraggono dall’altro (FIFO) AlgoLab - Pile e Code Operazioni sulle code Una coda (queue) si definisce astrattamente come una struttura dati su cui siano definite alemeno le operazioni: Enqueue(e,q) : aggiunge e come ultimo in q Dequeue(q) : elimina il primo in q Head(q) : ritorna il valore del primo in q IsEmpty(q): ritorna true se q non ha elementi. Nota: se q è vuota, Dequeue(q) e Head(q) sono indefinite. AlgoLab - Pile e Code Code realizzate con vettori (1) f r coda vuota q q f r 7 1 5 q f r 1 5 Dequeue(q) AlgoLab - Pile e Code Code realizzate con vettori (2) f r 5 2 q q r 9 f 5 2 Enqueue(9,q) L’indice della locazione successiva (sia per f che per r) si calcola: i + 1 mod n (n = lunghezza del vettore) AlgoLab - Pile e Code Code realizzate con vettori (3) q r f 9 3 5 2 coda piena Condizione necessaria perché una coda di lunghezza n sia piena è: r + 1 mod n = f Tale condizione tuttavia non è sufficiente, dato che si verifica anche in quello di coda vuota r f q coda vuota AlgoLab - Pile e Code Code realizzate con liste front … rear Come si realizza tutto questo in Java, sfruttando il più possibile le interfacce e l’ereditarietà? AlgoLab - Pile e Code