Un dizionario è una struttura dati astratta che contiene elementi accessibili direttamente, data la loro chiave. Nei nostri esempi assumiamo che le chiavi siano numeri naturali. Le operazioni supportate da un dizionario sono Insert
, Delete
e Search
.
Nel caso in cui le possibili chiavi siano un numero limitato, un'implementazione di un dizionario è un vettore di puntatori. Le chiavi vengono usate come indice del vettore, e le operazioni sul dizionario sono implementate come:
Insert(D,e)
: D[e.key] <- e
Delete(D,e)
: D[e.key] <- NIL
Search(D,e.key)
: return D[e.key]
Per ciascuna di queste operazioni si ha complessità computazionale
Una tabella hash implementa un dizionario con una complessità in memoria pari al numero di chiavi
Idealmente
Nel metodo dell'indirizzamento chiuso (anche chiamato open hashing o chaining) ogni riga della tabella (bucket) contiene la testa di una lista al posto del puntatore ad un singolo elemento. Nel caso di collisione l'elemento nuovo viene aggiunto in testa alla lista (
Nel caso pessimo tutti gli elementi collidono, dando origine ad una lista lunga Insert
/Delete
/Search
costeranno
Si ha che il numero medio di tentativi prima di trovare un elemento desiderato è:
Nel metodo dell'indirizzamento aperto (anche chiamato open addressing o closed hashing), in caso di collisione si seleziona secondo una regola deterministica l'indirizzo di un altro bucket di destinazione (procedimento di ispezione). Nel caso non si trovino bucket vuoti l'inserimento può fallire (
Si modifica inoltre la procedura di ricerca, affinché, se l'elemento non viene trovato nel suo bucket, essa effettui la stessa ispezione. La cancellazione è effettuata inserendo un opportuno valore (tombstone) che non corrisponde a nessuna chiave.
Il metodo di ispezione più semplice è l'ispezione lineare. Dato
Tuttavia se ci sono molte collisioni su un dato bucket, peggiorerà la probabilità di collisione in tutte le vicinanze. Questo fenomeno è detto clustering primario delle collisioni. Per alcune scelte di
Per mitigare il fenomeno del clustering è possibile utilizzare il criterio di ispezione quadratica, dove
Si ha che
Definiamo
È un metodo semplice:
Un altro metodo semplice è:
(uint32_t)(k * (double)ALPHA * ((uint64_t)1 << 32)))
Si può dimostrare che
Consideriamo il caso in cui il codominio di SHA-2-256
con