1 Un esempio: le liste ordinate di interi. 2 Liste ordinate  OrderedIntList 4 lista ordinata di interi –modificabile.

Slides:



Advertisements
Presentazioni simili
Estendere i linguaggi: i tipi di dato astratti
Advertisements

1 Astrazioni sui dati : Specifica ed Implementazione di Tipi di Dato Astratti in Java.
LIP: 4 Aprile 2008 ECCEZIONI. Eccezioni Come si definiscono eccezioni Come si lanciano Come si gestiscono (gestione esplicita o di default)
Liste di Interi Esercitazione. Liste Concatenate Tipo di dato utile per memorizzare sequenze di elementi di dimensioni variabile Definizione tipicamente.
MultiSet, Liste Ordinate
Le gerarchie di tipi.
Esercitazione Frame. Argomento Realizzazione di un tipo di dato astratto Usare le eccezioni per segnalare situazioni particolari Invariante e funzione.
LIP: 19 Aprile Contenuto Soluzione Compitino Tipo di dato MultiSet, estensione con sottoclasse.
Metodologie di Programmazione = decomposizione basata su astrazioni
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
PolyFun. Dare implementazione,funzione di astrazione, invarianti della rappresentazione. Provare che i metodi apply e bind preservano gli invarianti.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
Liste Ordinate 3 Maggio Ultima Lezione Abbiamo visto i tipi di dato astratti IntList e StringList Realizzano liste di interi e di stringhe Realizzati.
LIP: 1 Marzo 2005 Classe Object e Vettori. Partiamo da Lesercizio dellultima esercitazione realizzato tramite array Vedremo come si puo fare in modo piu.
Lez. 91 Universita' di Ferrara Facolta' di Scienze Matematiche, Fisiche e Naturali Laurea Specialistica in Informatica Algoritmi Avanzati Alberi di ricerca.
Alberi binari di ricerca
Fondamenti di Informatica II Ingegneria Informatica / Automatica (A-I) Meccanica Prof. M.T. PAZIENZA a.a – 3° ciclo.
Fondamenti di Informatica 2 Ingegneria Informatica Docente: Giovanni Macchia a.a
Esercizi su alberi binari
Alberi binari Definizione della struttura dati: struct tree { };
Algoritmi e Strutture Dati
Algoritmi e Strutture Dati IV. Heap e Code di Priorità
Modello dati ALBERO Albero: Albero: insieme di punti chiamati NODI e linee chiamate EDGES EDGE: linea che unisce due nodi distinti Radice (root): in una.
Modello dati ALBERO Albero: Albero: insieme di punti chiamati NODI e linee chiamate EDGES EDGE: linea che unisce due nodi distinti Radice (root): in una.
Esercizi su alberi binari
1 Le gerarchie di tipi. 2 Supertipi e sottotipi 4 un supertipo –class –interface 4 può avere più sottotipi –un sottotipo extends il supertipo ( class.
Per valutare la complessità ammortizzata scomponiamo ogni Union: nelle due FindSet e nella Link che la costituiscono e valuteremo la complessità in funzione.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti dispense prof. G. Levi.
Alberi binari Definizione della struttura dati: struct tree { };
Astrazione procedurale ed eccezioni
1 Un esempio con iteratore: le liste ordinate di interi.
Heap concetti ed applicazioni. maggio 2002ASD - Heap2 heap heap = catasta condizione di heap 1.albero binario perfettamente bilanciato 2.tutte le foglie.
Esercitazione su Vector. Permette di definire collezioni di dati generiche, che sono in grado di memorizzare elementi di ogni sottotipo di Object Definito.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterarare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
Liste di Interi Esercitazione. Una variante Liste concatenate di Integers Non modificabile Costruttori per creare la lista vuota o un nodo Metodi d’istanza.
Ripasso su Java. Introduzione Per risolvere problemi complessi, i linguaggi di programmazione forniscono costrutti per realizzare nuove funzioni che trasformino.
Liste di Interi Esercitazione. IntList Lista di interi Problema tipico: memorizzare una sequenza di valori [6,0,9,3….9] Vediamo un tipo di dato utile.
Compitino del 2004 Alberi Generici. Idea Si vuole un tipo di dato astratto che definisca una struttura ad albero in cui nodi e foglie hanno associato.
Liste Concatenate 11 Aprile E’ una delle strutture dati fondamentali in tutti i linguaggi di programmazione di alto livello Una Lista Concatenata.
Liste di Interi Esercitazione. IntList Lista di interi Una lista è una disposizione ordinata di elementi ( non in modo crescente-descrescente, ma per.
1 Gerarchie e polimorfismo: liste. 2 Generalizzare le liste di interi  List 4 lista di oggetti –non modificabile 4 vorremo poi definire un sottotipo.
Esercitazione Object, Vettori, Liste. Ereditarieta’ Abbiamo visto come tramite l’ereditarieta’ e’ possibile estendere classi esistenti -arricchendo lo.
1 Laboratorio di Introduzione alla Programmazione §II MODULO §3 crediti §Esame e voto unico (su 6 crediti totali)
LIP: 9 Maggio Esercizi Riprendiamo un esercizio proposto Definire un tipo di dato Persona che definisce oggetti che rappresentano le informazioni.
1 Progettare un Tipo di Dato Astratto. 2 Scelte di Progetto (astrazione) 4 Caratteristiche degli oggetti –Modificabilità 4 Scelta delle operazioni –Realizzare.
1 Astrazioni sui dati : Ragionare sui Tipi di Dato Astratti.
Ese 3 (del 3 Aprile 2003). Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi.
1 Le gerarchie di tipi: implementazioni multiple e principio di sostituzione.
Ese 3 (del 3 Aprile 2003). Testo Progettare la specifica e l’implementazione del tipo di dato astratto modificabile Stack, supponendo che gli elementi.
Ese 3 (del 31 Marzo 2004). Testo Dare rappresentazione e realizzazione dei metodi della seguente classe QueueWithPriority. Nella risposta, non riportare.
LIP: 22 Marzo 2005 Eccezioni. Eccezioni-Richiami Come si definiscono eccezioni Come si lanciano Come si gestiscono (gestione esplicita o di default)
1 Le s-espressioni. 2  Sexpr 4 alberi binari (possibilmente “vuoti”) che hanno sulle foglie atomi (stringhe) 4 sono la struttura dati base del linguaggio.
Esercizio 3. Testo Dare rappresentazione e realizzazione dei metodi della seguente classe QueueWithPriority. Nella risposta, non riportare i commenti.
PolyFun. Dare implementazione,funzione di astrazione, invarianti della rappresentazione. Provare che i metodi apply e bind preservano gli invarianti.
LIP: 2 Maggio 2008 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
1 Astrazione sul controllo: gli iteratori. 2 Perché vogliamo iterare “in modo astratto” 4 problema: iterare su tipi di dato arbitrari  esempio: procedura.
Sommario Oggetti immutabili e non Tipi Primitivi: String, Arrays.
Esercitazione. Problema Vogliamo definire in modo gerachico un tipo di dato che definisce Tabelle multi-dimensionali con un numero di righe variabili.
1 Metodologie di Programmazione = decomposizione basata su astrazioni.
Ese 1 e 3 (del 6 Aprile 2005). Primo Ese Si identifichino gli errori che il compilatore segnalerebbe per il seguente programma Tipi Legami tra dichiarazioni.
LIP: 11 Maggio 2007 Classi Astratte. Cos’e’ una Classe Astratta una classe astratta e’ un particolare tipo di classe permette di fornire una implementazione.
Esercitazione 14 Marzo Esercizio dell’altra volta Definire un tipo di dato Abbonato i cui oggetti descrivono le informazioni relative ad un abbonato.
Esercitazione del 9 marzo 2007 Ereditarieta’. Richiami Definire sottoclassi (ereditarieta’) Overriding Specificatori di accesso (private, protected) Principio.
Liste Concatenate 28 Marzo Avviso Martedi’ 4 Aprile: Verifica di LIP Per iscriversi (obbligatorio) inviare un e- mail entro venerdi’ 31 Marzo a.
1 Astrazioni polimorfe. 2 Perché il polimorfismo 4 Abbiamo visto come si definiscono insiemi di stringhe, insiemi di interi, insiemi di caratteri, etc.
1 Un esempio con iteratore: le liste ordinate di interi.
LIP: 4 Maggio 2007 Interfacce. Cos’e’ una Interfaccia una interfaccia e’ un particolare tipo di classe contiene solo la specifica non ha implementazione.
LIP: 15 Marzo 2005 Vettori di interi. Esercizio proposto Definire una classe VectorInt i cui oggetti sono vettori omogenei di interi ordinati in modo.
LIP: 18 Aprile 2008 Interfacce. Rappresentazione Lista val next vuota Lista vuota: any true Lista non vuota: any true 154 false 24 false.
Ex.1 - Astrazioni su Dati Si abbia il tipo di dato stack di interi, IntStack, specificato sotto: public class IntStack { \\ OVERVIEW: uno Stack è una collezione.
Transcript della presentazione:

1 Un esempio: le liste ordinate di interi

2 Liste ordinate  OrderedIntList 4 lista ordinata di interi –modificabile

3 Specifica di OrderedIntList 1 public class OrderedIntList { // OVERVIEW: una OrderedIntList è una lista // modificabile di interi ordinata // tipico elemento: [x1,..., xn], xi<xj se i<j // costruttore public OrderedIntList () // EFFECTS: inizializza this alla lista vuota // metodi public void addEl (int el) throws DuplicateException // MODIFIES: this // EFFECTS: aggiunge el a this, se el non occorre in // this, altrimenti solleva DuplicateException public void remEl (int el) throws NotFoundException // MODIFIES: this // EFFECTS: toglie el da this, se el occorre in // this, altrimenti solleva NotFoundException

4 Specifica di OrderedIntList 2 public boolean isIn (int el) // EFFECTS: se el appartiene a this ritorna // true, altrimenti false public boolean isEmpty () // EFFECTS: se this è vuoto ritorna true, altrimenti // false public int least () throws EmptyException // EFFECTS: se this è vuoto solleva EmptyException // altrimenti ritorna l’elemento minimo in this public boolean repOk () public String toString () // metodi test standard }

5 Specifica di OrderedIntList 3 public class OrderedIntList { public OrderedIntList () public void addEl (int el) throws DuplicateException public void remEl (int el) throws NotFoundException public boolean isIn (int el) public boolean isEmpty () public int least () throws EmptyException public boolean repOk () public String toString ()}  DuplicateException e NotFoundException checked

6 Come implementarla? 4 Potremmo usare una struttura dati lineare: lista concatenata 4 lista concatenata: definizione ricorsiva 4 o e’ vuota 4 o e’ formata da un nodo, che contiene un valore (di tipo int) ed un puntatore al resto della lista 4 bisognerebbe mantenere i nodi ordinati in base al valore associato in ordine crescente (tipo esercizio di LIP)

7 Usiamo invece un albero binario 4 albero binario: struttura ricorsiva tipo lista 4 o e’ vuoto 4 o contiene un nodo (detto radice) a cui e’ associato un valore (in questo caso di tipo int) ed un puntatore a due alberi, detti sottoalbero sinistro e destro rispettivamente 4 Nota: si chiama binario esattamente perche’ ogni nodo ha due figli (si puo’ generalizzare)

8 Esempio I nodi che puntano a sottoalberi vuoti si dicono foglie 4 Il nodo radice contiene 4

9 Commenti 4 Rispetto ai tipi di dato lineari, lista doppia –si può percorrere da ogni elemento in avanti o all’indietro 4 Mediamente piu’ efficiente la ricerca se i valori sono inseriti in modo opportuno 4 Complessita’ degli algoritmi di inserimento, ricerca, eliminazione etc… (LSD, Algoritimica)

10 Ordinamento 4 Per mantenere l’ordinamento richiediamo che, per ogni nodo a cui e’ associato n 4 tutti i valori contenuti nel sottoalbero sinistro abbiano valore strettamente minore di n, 4 tutti i valori contenuti nel sottoalbero destro abbiano valore strettamente maggiore di n.

11 Vantaggio 4 Se leggiamo i valori effettuando la visita dell’albero in ordine simmetrico otteniamo I valori ordinati in modo crescente 4 visita simmetrica: in modo ricorsivo, visitiamo prima il sottoalbero sinistro, poi la radice, poi il sottoalbero destro 4 Un esempio

12 Come lo implementiamo? public class OrderedIntList { // OVERVIEW: una OrderedIntList è una lista // modificabile di interi ordinata // tipico elemento: [x1,..., xn], xi<xj se i<j private boolean vuota; private OrderedIntList prima, dopo; private int val; 4 la rep contiene –una variabile boolean che ci dice se la lista è vuota –la variabile intera che contiene l’eventuale valore dell’elemento –due (puntatori a) OrderedIntList s che contengono la lista di quelli minori e quelli maggiori, rispettivamente 4 implementazione ricorsiva

13 Come è fatta ?  La lista vuota ha la variabile boolean true  Le foglie puntano alla lista vuota  Notate l’ordinamento 12F F 4 F FF T TF T T T T T

14 Commenti 4 L’invariante di rappresentazione e la funzione di astrazione descrivono le caratteristiche dell’implementazione che abbiamo in mente 4 Dipendono dalla rappresentazione e devono essere inserite come commenti alla rappresentazione 4 Sono fondamentali per ragionare sulla correttezza dell’implementazione o per capire l’implementazione (se per esempio qualcuno la dovesse modificare)

15 private boolean vuota; private OrderedIntList prima, dopo; private int val; I(c) = c.vuota oppure (c.prima != null e c.dopo != null e I (c.prima) e I (c.dopo) e (!c.prima.isEmpty() -> c.prima.max() < c.val) e (!c.dopo.isEmpty() -> c.dopo.least() > c.val) ) 4 l’invariante esprime le proprieta’ che devono soddisfare gli oggetti concreti, ovvero le loro variabili d’istanza 4 In questo caso il ruolo di vuota e la relazione tra i valori contenuti nella radice e nei sottoalberi (necessarie per garantire l’ordinamento richiesto) Invariante

16 private boolean vuota; private OrderedIntList prima, dopo; private int val;  (c) = se c.vuota allora [], altrimenti  (c) =  (c.prima) + [c.val] +  (c.dopo) 4 Mappa gli oggetti concreti, implementati con un albero binario, nella corrispondente lista ordinata in modo crescente, tipo [x1,..., xn], xi<xj se i<j 4 La funzione di astrazione ricorsiva realizza la lettura dei valori in modo simmetrico (dato che la lista deve essere ordinata) Funzione di astrazione

17 Esempio 4 Oggetto concreto x quello della figura 4 Oggetto astratto corrispondente e’ la seguente lista   (x)= [4,5,12,17,19]

18 Nota 4 Oggetto concreto, implementato tramite un albero binario, non e’e non deve essere visibile a chi usa OrderedIntList  Oggetto astratto (  (this) ) e’ visibile tramite il metodo toString () che implementa la funzione di astrazione 4 Fondamentale se vogliamo conoscere lo stato dell’oggetto su cui stiamo lavorando, pur non avendo accesso diretto alla rappresentazione 4 Permette di fare delle verifiche sul comportamento dei metodi (creo un oggetto, inserisco dei valori, vedo se il risultato e’ quello atteso)

19 Domanda 4 Se abbiamo due implementazioni diverse (una fatta con l’albero binario e l’altra con una lista concatenata) 4 Diverse invarianti e f. di astrazione 4 Ma gli oggetti astratti devono essere dello stesso tipo, quello descritto nella OVERVIEW [x1,..., xn], xi<xj se i<j 4 Da fuori vediamo solo gli oggetti astratti perche’ non vediamo differenze tra le due implementazioni (a parte chiaramente che possono differire in efficienza) 4 Principio di base del tipo di dato astratto: la specifica e’ l’interfaccia con l’esterno e maschera l’implementazione

20 Esercizio 4 Fate l’implementazione con lista concatenata (tipo LIP) 4 Formalizzate la funzione di astrazione e l’invariante 4 Verificate che l’invariante valga 4 Verificate la correttezza dei metodi 4 Dal punto di vista di chi usa il tipo di dato non deve vedersi differenza

21  (c) =  (c.prima) + [5] +  (c.dopo) = ([]+  4]+[]) + [5] + ([]+  8]+[])= [4, 5, 8] 4 Funzione di astrazione per il sottoalbero con radice 5 4 Se l’oggetto concreto non soddisfa l’invariante (che impone l’ordinamento) pero’ non e’ detto che troviamo I valori ordinati nel modo richiesto 4 Facciamo vedere che l’invariante impone dei vincoli sufficienti a garantire le proprieta’ dei dati richieste nella specifica Esempio

22 4 Facciamo vedere per induzione sulla lunghezza della lista che Se I(c) allora  (c) =[x1,..., xn], xi<xj se i<j  Caso Base: vale c.vuota.  Quindi  (c) = []. La lista vuota [] e’ ordinata. Invariante e Dati Astratti

23  Caso Induttivo: non vale c.vuota, ma (c.prima != null e c.dopo != null e I (c.prima) e I (c.dopo) e (!c.prima.isEmpty() -> c.prima.max() < c.val) e (!c.dopo.isEmpty() -> c.dopo.least() > c.val) )  Abbiamo  (c) =  (c.prima) + [c.val] +  (c.dopo)= [y1,..., yn]+ [c.val] + [z1,..., zk]  Dato che c.prima che c.dopo sono piu’ piccole di c, e che soddisfano l’invariante, allora per ipotesi induttiva [y1,..., yn] e [z1,..., zk] sono ordinate in modo crescente 4 Le altre proprieta’ dell’invariante garantiscono che sia anche tutta ordinata Invariante

24 4 L’invariante cattura le proprieta’ richieste nella specifica dei dati, in particolare l’ordinamento degli interi crescente (l’abbiamo fatto vedere) 4 Rimangono da implemenatre i metodi in modo che preservino l’invariante 4 Discutiamo anche la loro correttezza rispetto alla specifica, assumendo che l’invariante valga, e utilizzando la funzione di astrazione per collegare la specifica che parla di oggetti astratti e l’implementazione che si riferisce agli oggetti concreti Invariante

25 Implementazione public class OrderedIntList { // OVERVIEW: una OrderedIntList è una lista // modificabile di interi ordinata // tipico elemento: [x1,..., xn], xi<xj se i<j private boolean vuota; private OrderedIntList prima, dopo; private int val; // costruttore public OrderedIntList () // EFFECTS: inizializza this alla lista vuota { vuota = true; }  il costruttore inizializza solo la variabile vuota  l’oggetto prodotto soddisfa l’invariante ( c.vuota = true )  verifica la propria specifica (  (c) = [] )

26 Inserire e rimuovere 4 Difficili perche’ bisogna preservare l’ordinamento 4 Le proprieta’ dell’ordinamento sono espresse dall’invariante (ci aiuta a non fare errori in una situazione un po’ complessa) 4 Vediamo un esempio

27 public void addEl (int el) throws DuplicateException // MODIFIES: this // EFFECTS: aggiunge el a this, se el non occorre in // this, altrimenti solleva DuplicateException {if (vuota) { prima = new OrderedIntList(); dopo = new OrderedIntList(); val = el; vuota = false; return; } if (el == val) throw new DuplicateException(“OrderedIntList.addEl”); if (el < val) prima.addEl(el); else dopo.addEl(el); } 4 Ricorsiva, inserisce rispettando l’ordinamento 4 Propaga automaticamente l’eventuale eccezione sollevata dalle chiamate ricorsive Inserire un elemento

28 Esempio 4 vediamo la lista prodotta dalla sequenza di comandi OrderedIntList ls = new OrderedIntList(); ls.addEl(12); ls.addEl(5); ls.addEl(17); ls.addEl(4);ls.addEl(8); ls.addEl(19); 12F F 4 F FF T TF T T T T T

29 Invariante: per casi I(c) = c.vuota oppure (c.prima != null e c.dopo != null e I(c.prima) e I(c.dopo) e (!c.prima.isEmpty() -> c.prima.max() < c.val) e (!c.dopo.isEmpty() -> c.dopo.least() >= c.val) ) public void addEl (int el) throws DuplicateException {if (vuota) { prima = new OrderedIntList(); dopo = new OrderedIntList(); val = el; vuota = false; return; }... prima != null e dopo != null (calcolati dal costruttore) I (prima) e I (dopo) (calcolati dal costruttore) le implicazioni sono vere perché la premessa è falsa

30 Invariante: this non vuoto I(c) = c.vuota oppure (c.prima != null e c.dopo != null e I(c.prima) e I(c.dopo) e (!c.prima.isEmpty() -> c.prima.max() < c.val) e (!c.dopo.isEmpty() -> c.dopo.least() >= c.val) ) public void addEl (int el) throws DuplicateException... if (el < val) prima.addEl(el); else dopo.addEl(el); } 4 prima != null e dopo != null (this non e’ vuoto) I (prima) e I (dopo) (calcolati da una chiamata ricorsiva su una lista piu’ piccola)  ramo then: il nuovo massimo di prima è (induttivamente) minore di val  ramo else: il nuovo minimo di dopo è (induttivamente) maggiore di val

31 Specifica  (c) = se c.vuota allora [], altrimenti  (c.prima) + [c.val] +  (c.dopo) public void addEl (int el) throws DuplicateException // MODIFIES: this // EFFECTS: aggiunge el a this, se el non occorre in // this, altrimenti solleva DuplicateException {if (vuota) { prima = new OrderedIntList(); dopo = new OrderedIntList(); val = el; vuota = false; return; }...   (c pre ) = []   (c.prima) = [] e  (c.dopo) = [] e  c.val] = [el]   (c) = [el] (ha inserito l’elemento)

32 Specifica public class OrderedIntList { private boolean vuota; private OrderedIntList prima, dopo; private int val; //  (c) = se c.vuota allora [], altrimenti //  (c.prima) + [c.val] +  (c.dopo) public void addEl (int el) throws DuplicateException // MODIFIES: this // EFFECTS: aggiunge el a this, se el non occorre in // this, altrimenti solleva DuplicateException... if (el == val) throw new DuplicateException(“OrderedIntList.addEl”); 4 se ci sono elementi duplicati solleva l’eccezione, eventualmente propagando eccezioni sollevate dalle chiamate ricorsive (vedi dopo)

33 Specifica //  (c) = se c.vuota allora [], altrimenti //  (c.prima) + [c.val] +  (c.dopo) public void addEl (int el) throws DuplicateException // MODIFIES: this // EFFECTS: aggiunge el a this, se el non occorre in // this, altrimenti solleva DuplicateException... if (el < val) prima.addEl(el); else dopo.addEl(el); } 4  (c pre ) =  (c.prima pre ) + [c.val] +  (c.dopo pre )  se el < val la chiamata ricorsiva solleva l’eccezione oppure produce   (c.prima) = aggiunge el a prima pre 4  (c.dopo) =  (c.dopo pre ) 4  (c) = aggiunge el a c pre 4 Analogo nel caso simmetrico

34 Rimuovere un elemento 4 Difficile, bisogna mantenere l’ordinamento 4 Supponiamo di dovere rimuovere 12 (e’ la radice) 4 Non possiamo semplicemente spostare nella radice uno dei nodi figli (ex. 5)

35 Idea 4 si prende il valore minimo del dopo (se c’e’) e si mette al posto della radice (e si rimuove dal dopo) 4 e’ di sicuro piu’ grande di tutti i valori di prima e piu’ piccolo di quelli di dopo 4 se dopo e’ vuoto allora si ricopia nel nodo radice il sottoalbero prima 4 in questo modo viene preservato l’ordinamento imposto dall’ordinamento

36 Implementazione di OrderedIntList 5 public void remEl (int el) throws NotFoundException // MODIFIES: this // EFFECTS: toglie el da this, se el occorre in // this, altrimenti solleva NotFoundException {if (vuota) throw new NotFoundException(“OrderedIntList.remEl”); if (el == val) try { val = dopo.least(); dopo.remEl(val); } catch (EmptyException e) { vuota = prima.vuota; val = prima.val; dopo = prima.dopo; prima = prima.prima; return;} else if (el < val) prima.remEl(el); else dopo.remEl(el); }

37 Implementazione di OrderedIntList 6 public boolean isIn (int el) // EFFECTS: se el appartiene a this ritorna // true, altrimenti false {if (vuota) return false; if (el == val) return true; if (el < val) return prima.isIn(el); else return dopo.isIn(el); } public boolean isEmpty () // EFFECTS: se this è vuoto ritorna true, altrimenti false {return vuota; } Si ricerca in base all’ordinamento (efficiente, non si visita tutto)

38 Implementazione di OrderedIntList 6.1 public class OrderedIntList { private boolean vuota; private OrderedIntList prima, dopo; private int val; //  (c) = se c.vuota allora [], altrimenti //  (c.prima) + [c.val] +  (c.dopo) public boolean isIn (int el) // EFFECTS: se el appartiene a this ritorna // true, altrimenti false {if (vuota) return false; if (el == val) return true; if (el < val) return prima.isIn(el); else return dopo.isIn(el); } public boolean isEmpty () // EFFECTS: se this è vuoto ritorna true, altrimenti false {return vuota; } 4 dimostrazioni di correttezza ovvie, visto che l’invariante che garantisce l’ordinamento

39 Implementazione di OrderedIntList 7.1 public class OrderedIntList { private boolean vuota; private OrderedIntList prima, dopo; private int val; public int least () throws EmptyException // EFFECTS: se this è vuoto solleva EmptyException // altrimenti ritorna l’elemento minimo in this {if (vuota) throw new EmptyException(“OrderedIntList.least”); try { return prima.least(); } catch (EmptyException e) {return val;} } 4 dimostrazione di correttezza ovvia usando l’invariante, che garantisce l’ordinamento  Ritorna proprio il primo elemento di  (this)

40 Implementazione di OrderedIntList 7.1 public class OrderedIntList { private boolean vuota; private OrderedIntList prima, dopo; private int val; public String toString(){ // EFFECTS:standard {if (vuota) return “”; return prima.toString() + val + dopo.toString(); } } 4 dimostrazione di correttezza ovvia usando l’invariante, che garantisce l’ordinamento  Implementa  (this) visita in ordine simmetrico