ADT Insieme L'ADT Insieme è un contenitore di oggetti distinti. non esistono due elementi uguali; non esiste un ordinamento sugli oggetti. Strutture Dati ADT Insieme Metodi fondamentali dell'ADT Insieme Metodi applicati all'insieme A (this): void union (Set B): rimpiazza A con l'unione insiemistica di A e B void intersect (Set B): rimpiazza A con l'intersezione insiemistica di A e B void subtract (Set B): rimpiazza A con la differenza insiemistica A-B Strutture Dati ADT Insieme Interfaccia public interface Set<E> { public int size(); public boolean isEmpty(); /**Rimpiazza this con l'unione di this e B */ public void union(Set<E> B); /**Rimpiazza this con l'intersezione di this e B */ public void intersect(Set<E> B); /**Rimpiazza this con la differenza di this e B */ public void subtract(Set<E> B); } Strutture Dati ADT Insieme Implementazione con lista ordinata definire una relazione d'ordine totale (qualunque) sugli oggetti usare una variabile istanza per la lista ed una per il comparatore scrivere una classe astratta contenente un metodo merge, una generica versione dell'algoritmo merge (usato nel mergesort) scrivere tre sottoclassi distinte che specializzano merge rispettivamente in: - union - intersect - subtract Strutture Dati ADT Insieme Implementazione con lista ordinata classe astratta Merge<E> metodo merge generico sottoclasse UnionMerge<E> Strutture Dati sottoclasse IntersectMerge<E> sottoclasse SubtractMerge<E> ADT Insieme Implementazione con lista ordinata public class ListSet<E> extends Merge<E> implements Set<E>{ protected PositionList<E> A; dell'insieme protected Comparator<E> comp; ... } Strutture Dati //la lista che contiene gli elementi ADT Insieme Implementazione con lista ordinata public abstract class Merge<E> { private E a, b; // elementi correnti in A e B private Iterator<E> iterA, iterB; // iteratori per A e B //metodi ausiliari private boolean advanceA() if (iterA.hasNext()) { a return false; } private boolean advanceB() if (iterB.hasNext()) { b return false; } ... } Strutture Dati { = iterA.next(); return true; } { = iterB.next(); return true; } ADT Insieme Implementazione con lista ordinata public abstract class Merge<E> { ... // metodi ausiliari da specializzare nelle sottoclassi protected void aIsLess(E a, PositionList<E> C) { } protected void bothAreEqual(E a, E b, PositionList<E> C) { } protected void bIsLess(E b, PositionList<E> C) { } } Strutture Dati ADT Insieme Implementazione con lista ordinata public abstract class Merge<E> { ... /** Metodo merge generico*/ public void merge(PositionList<E> A, PositionList<E> B, Comparator<E> comp, PositionList<E> C) { iterA = A.iterator(); iterB = B.iterator(); boolean aExists = advanceA(); boolean bExists = advanceB(); //ciclo principale del metodo merge generico while (aExists && bExists) { int x = comp.compare(a, b); if (x < 0) { aIsLess(a, C); aExists = advanceA(); } else if (x == 0) { bothAreEqual(a, b, C); aExists = advanceA(); bExists = advanceB(); } else { bIsLess(b, C); bExists = advanceB(); } } while (aExists) { aIsLess(a, C); aExists = advanceA(); } while (bExists) { bIsLess(b, C); bExists = advanceB(); } } ... } Strutture Dati ADT Insieme Implementazione con lista ordinata Implementazione di union (classe UnionMerge<E>) A a caso a < b B b C Strutture Dati Laboratorio di Algoritmi e Strutture Dati ADT Insieme Implementazione con lista ordinata Implementazione di union (classe UnionMerge<E>) A a caso a < b B b metodo aIsLess(a,C) : C a Strutture Dati - aggiunge a C l'elemento a ADT Insieme Implementazione con lista ordinata Implementazione di union (classe UnionMerge<E>) A a caso a = b B b C Strutture Dati ADT Insieme Implementazione con lista ordinata Implementazione di union (classe UnionMerge<E>) A a caso a = b B b metodo bothAreEqual(a,b,C) : C a Strutture Dati - aggiunge a C l'elemento a e non il suo duplicato b ADT Insieme Implementazione con lista ordinata Implementazione di union (classe UnionMerge<E>) A a caso a > b B b C Strutture Dati ADT Insieme Implementazione con lista ordinata Implementazione di union (classe UnionMerge<E>) A a caso a > b B b metodo bIsLess(b,C) : C b Strutture Dati - aggiunge a C l'elemento b ADT Insieme Implementazione con lista ordinata Implementazione di intersect (classe IntersectMerge<E>) A a caso a < b B b C Strutture Dati ADT Insieme Implementazione con lista ordinata Implementazione di intersect (classe IntersectMerge<E>) A a caso a < b B b metodo aIsLess(a,C) : C Strutture Dati ...non fa nulla! ADT Insieme Implementazione con lista ordinata Implementazione di intersect (classe IntersectMerge<E>) A a caso a = b B b C Strutture Dati ADT Insieme Implementazione con lista ordinata Implementazione di intersect (classe IntersectMerge<E>) A a caso a = b B b metodo bothAreEqual(a,b,C) : C a Strutture Dati - aggiunge a C l'elemento a ADT Insieme Implementazione con lista ordinata Implementazione di intersect (classe IntersectMerge<E>) A a caso a > b B b C Strutture Dati ADT Insieme Implementazione con lista ordinata Implementazione di intersect (classe IntersectMerge<E>) A a caso a > b B b metodo bIsLess(b,C) C Strutture Dati ...non fa nulla! ADT Insieme Implementazione con lista ordinata public class UnionMerge<E> extends Merge<E>{ protected void aIsLess(E a, PositionList<E> C) { C.addLast(a);// aggiunge a } protected void bothAreEqual(E a, E b, PositionList<E> C) { C.addLast(a); // aggiunge a (ma non il suo duplicato b) } protected void bIsLess(E b, PositionList<E> C) { C.addLast(b); // aggiunge b } } Strutture Dati ADT Insieme Implementazione con lista ordinata public class IntersectMerge<E> extends Merge<E>{ protected void aIsLess(E a, PositionList<E> C) { } protected void bothAreEqual(E a, E b, PositionList<E> C) { C.addLast(a); // aggiunge a (ma non il suo duplicato b) } protected void bIsLess(E b, PositionList<E> C) { } } Strutture Dati ADT Insieme Implementazione con lista ordinata public class SubtractMerge<E> extends Merge<E>{ protected void aIsLess(E a, PositionList<E> C) { C.addLast(a); // aggiunge a } protected void bothAreEqual(E a, E b, PositionList<E> C) { } protected void bIsLess(E b, PositionList<E> C) { } } Strutture Dati ADT Insieme Implementazione con lista ordinata public class ListSet<E> extends Merge<E> implements Set<E>{ protected PositionList<E> A;//lista che contiene gli elementi dell'insieme protected Comparator<E> comp; /**Costruttore che crea un insieme vuoto*/ public ListSet() { A = new NodePositionList<E>(); comp = new DefaultComparator<E>(); } public void union(Set<E> B) { PositionList<E> C = new NodePositionList<E>(); Merge<E> op = new UnionMerge<E>(); op.merge(A, B.elements(),comp,C); A=C; } ... } Strutture Dati ADT Insieme Implementazione con lista ordinata Complessità ● merge: O(nA + nB) (nA : numero di elementi in A; nB : numero di elementi in B) Le operazioni union, intersect e subtract possono essere implementate in tempo O(n). (n : numero di elementi totale degli insiemi coinvolti) Strutture Dati ADT Insieme Completare l' implementazione di Set aggiungendo anche l'implementazione dei seguenti metodi: elements(): restituisce la lista degli elementi dell'insieme; iterator(): restituisce un iteratore sugli elementi dell'insieme; insert(e): inserisce un nuovo elemento e nell'insieme; Strutture Dati