Sei sulla pagina 1di 11

Il TDA Set

Il TDA Set „ Un insieme è un contenitore di oggetti


distinti
– Non esiste un’esplicita nozione di chiavi
– Non esiste un ordinamento degli elementi
Union-Find „ Se esiste una relazione d’ordine totale
sugli elementi di un insieme, possiamo
implementare in maniera efficiente le
operazioni sugli insiemi

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 2

Interfaccia Set
Operazioni sul TDA Set public interface Set {
// Restituisce il numero degli elementi nell’insieme
public int size();
„ Le operazioni che possiamo fare su di
// Restituisce true se l’insieme è vuoto
un insieme A sono: public boolean isEmpty();
– union(A,B) // Rimpiazza this con l’unione di this e B
• Rimpiazza A con l’unione di A e B public Set union(Set B);
– intersect(A,B) // Rimpiazza this con l’intersezione di this e B
• Rimpiazza A con l’intersezione di A e B public Set intersect(Set B);

– subtract(A,B) // Rimpiazza this con la differenza di this e B


• Rimpiazza A con la differenza di A e B public Set subtract(Set B);
}
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 3 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 4
Implementazione di Set – 1 Implementazione di Set – 2

„ Il modo più semplice per implementare „ Implementando l’interfaccia Set tramite


il TDA insieme è quello di memorizzare una lista, lo spazio usato è O(n)
gli elementi dell’insieme in una
Nodi che memorizzano gli elementi dell’insieme
sequenza (List, Vector, Sequence)
– Ad esempio, la classe che implementa Set Lista ∅
avrà una variabile istanza di tipo Vector
(conterrà gli elementi dell’insieme) ed una
di tipo EqualityTester (usata per
confrontare elementi dell’insieme) Elementi dell’insieme

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 5 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 6

Metodi ulteriori – 1 Metodi ulteriori – 2

„ L’implementazione oltre a contenere i „ public Object insert(Object element)


– Inserisce element nell’insieme restituendolo
metodi indicati nell’interfaccia Set, potrà
– Se element è già presente nell’insieme non lo
contenere i metodi: inserisce restituendo null
– public boolean contains(Object element) „ public Object remove(Object element)
• Restituisce true se element appartiene – Cancella element dall’insieme restituendolo
all’insieme – Restituisce null se element non è presente
• Restituisce false se element non appartiene „ public Object remove()
all’insieme – Cancella l’ultimo elemento dell’insieme
restituendolo, restituisce null se l’insieme è vuoto
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 7 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 8
Possibile implementazione Complessità
public class ListSet implements Set { „ Indichiamo con n ed m il numero degli
EqualityTester eq; elementi degli insiemi A e B, rispettivamente
List L;

ListSet() { „ La complessità dei metodi A.insert(e),


L = new NodeList(); A.contains(e) e A.remove(e) è O(n)
eq = new DefaultEqualityTester();
}
„ La complessità dei metodi A.union(B),
...
A.intersect(B) e A.subtract(B) è O(n·m)
}
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 9 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 10

Sequenze ordinate Esercizi


„ Se gli elementi che inseriamo negli insiemi
soddisfano una relazione di ordine totale, „ Implementare la classe ListSet
allora possiamo memorizzarli in una
sequenza ordinata „ Implementare l’interfaccia Set usando
„ L’implementazione dovrà utilizzare un’istanza come rappresentazione dell’insieme
di Comparator al posto di EqualityTester – Il TDA Sequence
„ È possibile usare lo schema della procedura
merge usata nell’ordinamenento per fusione – Il TDA Vector
(MergeSort) per implementare i metodi: „ Sviluppare la classe OrderedListSet che
union, intersect, subtract implementa l’interfaccia Set usando una
„ Come cambia la complessità dei metodi delle lista ordinata
slide precedenti?
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 11 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 12
Rappresentazione degli elementi – 1 Rappresentazione degli elementi – 2
„ Invece di rappresentare un elemento di un
„ Un elemento conosce a quale insieme
insieme con la classe Object possiamo farlo
attraverso una classe che contiene due appartiene
campi
– Object element
„ Alcune operazioni possono essere
• Rappresenta l’elemento stesso
– Set set implementate più efficientemente
• È il riferimento all’insieme che contiene l’elemento rispetto alla rappresentazione
• Se set è null, allora l’elemento non appartiene ad alcun precedente
insieme.

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 13 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 14

Interfaccia Element Classe SetAwareElement

public interface Element { public class SetAwareElement


implements Element {
public Set set();
Object element;
public Object element(); Set set;
...
} }
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 15 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 16
Metodi di SetAwareElement Esercizi

„ public SetAwareElement(Object el) „ Implementare la classe


„ public SetAwareElement(Set s, Object el) SetAwareElement
„ public Set set() „ Implementare l’interfaccia Set

„ public Object element()


utilizzando la classe SetAwareElement
per rappresentare gli elementi
„ public Set assignSet(Set s)
dell’insieme (non ordinato)
„ public Object assignElement(Object el) – Sviluppare la classe ListAwareSet

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 17 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 18

Note su ListAwareSet Metodo checkElement

„ Metodi modificati di ListAwareSet protected SetAwareElement checkElement(Element el)


throws InvalidElementException
– public boolean contains(Element el) {
– public Object insert(Element el) if(el == null || !(el instanceof SetAwareElement))
– public Object remove(Element el) throw new InvalidElementException("Elemento non
valido");
return (SetAwareElement) el;
„ La classe deve implementare anche il }
metodo protetto checkElement

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 19 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 20
Il TDA Partition Interfaccia Partition – 1
„ Una partizione è una collezione di
public interface Partition {
insiemi S1,…,Sk a due a due disgiunti
// Restituisce il numero degli insiemi nella partizione
– Si ∩ Sj = ∅ per ogni i ≠ j
public int size();
„ TDA Partition supporta i seguenti metodi:
– makeSet(x) // Restituisce true se la partizione è vuota
• Crea l’insieme contenente il solo elemento x
public boolean isEmpty();
– union(A, B)
• Unisce gli insiemi A e B distruggendo B e
restituendo A // Restituisce l’insieme contenente il solo elemento x
– find(x) public Set makeSet(Object x);
• Restituisce l’insieme che contiene l’elemento x

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 21 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 22

Interfaccia Partition – 2 Implementazione del TDA Partition


„ Ogni insieme nella partizione è rappresentato
// Sostituisce A con l’unione di A e B, distruggendo B
da una sequenza (Vector, List, Sequence)
// e restituendo A
– Oppure da una classe che implementa il TDA Set
public Set union(Set A, Set B);

// restituisce l’insieme che contiene l’elemento x


„ In una sequenza (Vector, List, Sequence)
public Set find(Object x);
inseriamo tutti i riferimenti agli insiemi nella
partizione
}
– Ogni insieme creato nella partizione verrà inserito
in questa sequenza

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 23 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 24
Nota Interfaccia PartitionAware
public interface PartitionAware {
„ Ad ogni elemento dobbiamo associare
l’insieme a cui appartiene public int size();

– Rappresentiamo gli elementi con la classe public boolean isEmpty();


SetAwareElement
public Set makeSet(Element x);
– Nella partizione c’è una mappa che ha
public Set union(Set A, Set B);
come voci le coppie (elemento, insieme)
• Rappresentiamo mappa con una tabella hash public Set find(Element x);
• Serve per implementare efficientemente find
}

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 25 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 26

A B
5 11 8 2 9 3 1 La classe HashTablePartition

partizione public class HashTablePartition


implements Partition{
C
Map elementi; //implementata con una
17 4 12 6 16 //tabella hash
Vector partizione;
4, 12, 5, 11, 1, …
......
h(4) h(12) h(5) h(11) h(1) }
elementi
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 27 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 28
Nota su Partition – 1 Nota su Partition – 2

„ Dato che in una partizione gli insiemi „ public Object fastInsert(Object x)


sono due a due disgiunti, siamo sicuri – Inserisce, all’inizio dell’insieme A,
che un elemento apparterrà solo ad un l’elemento x senza verificare se x
appartiene ad A
insieme. Di conseguenza possiamo
– Complessità O(1)
aggiungere all’implementazione di
„ public Set fastUnion(Set A, Set B)
Partition i metodi
– Unisce gli insiemi A e B senza verificare se
– public Set fastUnion(Set A, Set B) gli elementi di B appartengono ad A
– public Object fastInsert(Object x) – Complessità O(|B|), se si usa fastInsert
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 29 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 30

Note su union(Set A, Set B) – 1 Note su union(Set A, Set B) – 2


„ Non cancelliamo tutti e due gli insiemi
„ Quando si esegue un’unione, spostiamo
sempre gli elementi dall’insieme più piccolo a ma solo quello più piccolo
quello più grande „ Per cancellare un insieme dovremmo
– Ogni volta che spostiamo un elemento, esso va a
finire in un insieme che è almeno due volte più conoscere la sua posizione nella
grande dell’insieme da cui proviene sequenza (partizione) che memorizza i
– In questo modo, un elemento può essere mosso al riferimenti di tutti gli insiemi nella
più O(log n) volte
partizione
„ Per ogni elemento spostato aggiorniamo la
mappa (insieme a cui appartiene) – Se la partizione è rappresentata con un
Vector o Sequence possiamo scorrere
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 31 tutto
Prof. Carlo Blundo il Vector
Laboratorio dio tutta
Algoritmi la DatiSequence per
e Strutture 32

cercare l’insieme e poi rimuoverlo (non c’è


Note su union(Set A, Set B) – 2
A B
„ Se la partizione è rappresentata con List,
5 11 8 2 9 3 1
allora c’è un metodo più efficiente per
cancellare l’insieme
„ Inseriamo come ultimo elemento dell’insieme Part
X un elemento che conserva il riferimento
alla posizione occupata da X in partizione C
– Il metodo makeSet inserisce come ultimo
17 4 12 6 16
elemento il riferimento all’insieme appena creato

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 33 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 34

Rappresentazione basata su albero – 1


Metodo union(Set A, Set B)
„ Ogni insieme nella partizione è visto come un albero
union(Set A, Set B) { „ Ogni elemento di un insieme è memorizzato in una
posizione (nodo dell’albero)
Position p = (Position) B.remove(); „ Un elemento appartiene all’insieme corrispondente alla
while(!B.isEmpty()) { radice (nodo che punta a se stesso) del suo albero
„ Esempio degli insiemi “1”, “2” e “5”
A.fastInsert(B.remove());
// Aggiornamento mappa 1 2 5
}
4 7 3 6 8 10
partizione.remove(p);
} 9 11
12
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 35 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 36
Rappresentazione basata su albero – 2 Il metodo union
„ Ogni posizione è implementata con un nodo
contenente
– element: riferimento all’elemento dell’insieme „ Per eseguire una
– parent: riferimento al nodo padre (a se stesso per union, si fa puntare
la radice) semplicemente la 5
– size numero di elementi nel sottoalbero, 2
aggiornato solo per la radice radice di un albero
8 10
„ Gli alberi usati sono specifici per Partition non alla radice dell’altro 3 6
costituiscono un’implementazione del TDA Tree 11
„ Anche in questa implementazione possiamo 9 12
usare una mappa o un SetAwareElement per
conservare il riferimento all’insieme che contiene
un dato elemento
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 37 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 38

Il metodo find Esercizi


„ Per eseuire una „ Implementare l’interfaccia Partition tramite
find, si segue il una classe TreePartition che rappresenta
5
puntatore al genitore ogni insieme nella partizione con un albero i
2
dal nodo che 8 10 cui nodi contengono gli elementi
contiene l’elemento 3 6
passato in input fino 11
dell’insieme ed ogni nodo ha un solo
a quando non si 9 12
riferimento al nodo genitore
arriva alla radice – È necessario modificare l’interfaccia Partition?
(nodo che punta a 12, „ Scrivere un programma Java per testare la
se stesso) classe sviluppata al punto precedente
…. h(12) ….
Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 39 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 40
Miglioramenti – 1 Miglioramenti – 2
„ Union-by-size
„ Path Compression
– nelle operazioni di unione rendi l’insieme più piccolo
sottoalbero della radice dell’altro – Dopo aver eseguito un’operazione find(x), tutti i nodi
– Si usa un campo aggiuntivo nei nodi per memorizzare la attraversati nella ricerca avranno come nodo genitore la
taglia del sottoalbero radice
5 5

5
8 10 8 10
5
2
2 11 11
8 10
8 10 2 12 2 12
3 6
3 6
11 3 6 3 6
11
9 12
9 12 9 9

Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 41 Prof. Carlo Blundo Laboratorio di Algoritmi e Strutture Dati 42

Potrebbero piacerti anche