Concatenamento

Un modo per risolvere le collisioni consiste nello sfruttare le linked list per metterle su ogni cella, per poi inserirci tutti gli elementi che hanno chiavi diverse ma hash uguali.

In questo caso, le implementazioni sono:

  • search(T, x) in tempo proporzionale alla lunghezza della lista su T[h(x.key)]
  • insert(T, x) in inserendo x in testa a T[h(x.key)]
  • delete(T, x) in se x.prev è presente, altrimenti come search

Tempo di ricerca

Nel caso peggiore tutti gli elementi sono nella stessa cella, e quindi il tempo di search è , mentre nel caso medio il tempo dipende dalla distribuzione delle chiavi fra le celle.

Una distribuzione ideale di è data dall'hashing uniforme e indipendente, per cui: da cui si ricava il fattore di carico .

In questo caso, la lunghezza media di una lista lunga su T[i] è: Di conseguenza, la ricerca senza successo avviene in , perchè è almeno ma . La ricerca con successo invece, avviene in , perchè in media arriva fino a metà lista.

Per cui, finchè si ha perchè è uniforme, altrimenti quando cresce T va riallocato.

Funzione hash

Quando le chiavi vanno trasformate, per esempio attraverso la notazione posizionale: dove è il numero di valori rappresentabili in bit per carattere nella codifica ASCII, i.e. base .

In generale, per diminuire le collisioni si può usare la tecnica di hashing universale per cui la funzione viene scelta casualmente da una famiglia di funzioni uniformi all'inizio del programma.

Divisione

risulta essere semplice, ma richiede un'accurata scelta di :

  • perchè altrimenti considera solo i bit meno significativi, scartando gli altri
  • se è una stringa in base , perchè altrimenti le permutazioni di danno lo stesso
  • dove è un numero primo distante da potenze di e

Moltiplicazione

con , fissando e ottenendo da un valore in da trasformare in .

In questo modo non è più critico e la funzione è ottimale per la maggior parte degli , tra cui .

Se è una word lunga , la funzione si può semplificare scegliendo una tra le word e ponendo: così che restituisca i bit più significativi di , ovvero ((k*q) & ((1 << w)-1)) >> (w-p).