ADT Dizionario
Come nella Mappa:
●
un Dizionario è un contenitore di elementi del tipo (k,v) dove k è la
chiave e v è il suo corrispondente valore.
●
ogni elemento (k,v) viene detto entrata (entry) del Dizionario.
●
chiavi e valori possono essere oggetti di qualsiasi tipo.
Diversamente dalla Mappa:
●
sono permesse entrate multiple con la stessa chiave.
Strutture Dati
ADT Dizionario
Esistono due tipi di dizionari:
●
●
dizionari non ordinati (non è definita alcuna relazione d'ordine totale
sulle chiavi: l'unico test permesso fra chiavi è quello di uguaglianza)
dizionari ordinati (è definita una relazione d'ordine totale sulle chiavi)
Strutture Dati
ADT Dizionario
Metodi fondamentali
–
size(): restituisce il numero di entrate in D.
–
isEmpty(): verifica se D è vuoto.
–
find(k): se D contiene una entrata con chiave k, restituisce tale
entrata, altrimenti restituisce null.
–
findAll(k): restituisce una collezione iterabile contenente tutte le
entrate con chiave k.
–
insert(k,v): inserisce una entrata con chiave k e valore v in D;
restituisce l'entrata creata.
–
remove(e): rimuove da D una entrata e, restituendo l'entrata
rimossa; si ha un errore se e non è in D.
–
entries(): restituisce una collezione iterabile delle entrate in D.
Strutture Dati
ADT Dizionario
Interfaccia
public interface Dictionary<K,V> {
public int size();
public boolean isEmpty();
public Entry<K,V> find(K key)
throws InvalidKeyException;
public Iterable<Entry<K,V>> findAll(K key)
throws InvalidKeyException;
public Entry<K,V> insert(K key, V value)
throws InvalidKeyException;
public Entry<K,V> remove(Entry<K,V> e)
throws InvalidEntryException;
public Iterable<Entry<K,V>> entries();
}
Strutture Dati
ADT Dizionario
Implementazione con liste non ordinate
lista S
Le entrate del dizionario D vengono mantenute in una lista
non ordinata S
non è definita alcuna relazione d'ordine totale sulle chiavi
Strutture Dati
ADT Dizionario
Implementazione con liste non ordinate
Algorithm findAll(k):
Crea una lista S inizialmente vuota
for each entry e in D.entries() do
if e.getkey() = k then
S.addLast(e)
return S
Algorithm insert(k,v):
Crea una nuova entrata e = (k,v)
S.addLast(e)
{lecito perché S non è ordinata}
return e
Strutture Dati
ADT Dizionario
Implementazione con liste non ordinate
Algorithm remove(e):
{assumiamo che e non memorizzi la sua position in S}
for each position p in S.positions() do
if p.element() = e then
S.remove(p)
return e
lancia una InvalidEntryException {non esiste l'entrata e in D}
Algorithm entries():
return S
Strutture Dati
ADT Dizionario
Implementazione con liste non ordinate
Analisi:
spazio: O(n)
tempo:
●
●
insert: O(1)
find e remove: O(n) (nel caso pessimo si deve scorrere tutta la lista)
la performance di remove può essere portata ad O(1) se ogni entrata
di D memorizza la sua posizione nella lista S
Questa implementazione è opportuna solo per dizionari di piccola taglia o
dizionari in cui gli inserimenti sono le operazioni più comuni, mentre le ricerche e
le rimozioni sono eseguite di rado (per esempio record di login a una workstation)
Strutture Dati
ADT Dizionario
Implementazione con tabelle hash
Possiamo usare una tabella hash con separate chaining per
risolvere le collisioni
Bucket array A
Dizionario basato su lista
0
1
2
3
4
…
Ogni cella A[i] mantiene un dizionario che contiene tutte le entrate con
chiave k tale che h(k) = i
Strutture Dati
ADT Dizionario
Implementazione con tabelle hash
A: bucket array
N: dimensione del bucket array
n: numero di entrate del dizionario
λ: massimo load factor della tabella hash
h: funzione hash
Algorithm insert(k,v):
if (n + 1) / N > λ then
raddoppia la taglia del bucket array e fai il rehash delle chiavi
e := A[h(k)].insert (k,v)
n:= n + 1
A[h(k)] è un dizionario
return e
quindi possiamo usare il
metodo insert per inserire
una nuova entrata
Strutture Dati
ADT Dizionario
Implementazione con tabelle hash
Algorithm findAll(k):
return A[h(k)].findAll (k)
Algorithm remove(e):
t := A[h(k)].remove (e)
n=n–1
return t
Strutture Dati
ADT Dizionario
Implementazione con tabelle hash
Analisi:
spazio: O(n)
tempo:
●
●
●
●
insert: O(1)
remove:
● atteso: O(1)
● caso peggiore: O(n)
find:
● atteso: O(1)
● caso peggiore: O(n)
findAll:
● atteso: O(1 + s) dove s è il numero di chiavi restituite.
● caso peggiore: O(n)
Strutture Dati