Indirizzamento aperto

Un modo alternativo per risolvere le collisioni consiste nel memorizzare gli elementi con lo stesso hash nella tabella insieme agli altri, per poi cercarli attraverso l'ispezione di T[h(k)]:

  • Se la cella equivale a k la ricerca ha successo
  • Se equivale a NIL la ricerca termina con insuccesso
  • Se è diversa da k si trova il prossimo indice dall'ordine di ispezione, cioè il numero di ispezioni fatte

Si vuole quindi che la funzione hash rappresenti la posizione di in T dopo ispezioni fallite: con la condizione che per ogni la funzione assuma tutti i valori, così che ogni cella possa essere usata.

Implementazione

In queste versioni delle operazioni, per semplicità, gli elementi di T sono solamente le chiavi stesse.

  • Inserimento

    insert(T, k)
      i = j = 0
      found = false
      while not found and i < m
        j = h(k, i)
        if T[j] == NIL or T[j] == DELETED
          T[j] = k
          found = true
        else
          i++
      if found
        return j
      return NIL
    
  • Ricerca

    search(T, k)
      i = j = 0
      found = false
      do
        j = h(k, i)
        if T[j] == k
          found = true
        else
          i++
      while not found and i < m and T[j] != NIL
      if found
        return j
      return NIL
    
  • Cancellazione

    delete(T, k)
      T[search(T, k)] = DELETED
    

    Il motivo per cui si usa DELETED invece che NIL è che quest'ultimo serve ad indicare la fine della catena di ricerca, e quindi porterebbe alla perdita dei valori sulle successive.

    Lo svantaggio di questo metodo è che il tempo di ricerca non dipende più da .

Metodi di ispezione

Come per il concatenamento, una funzione ideale rispetterebbe le proprietà dell'hashing uniforme così che, dato un , ogni è distribuito uniformemente sulle celle.

Dato che è difficile rispettarle, vengono adottate delle approssimazioni.

Ispezione lineare

dove è detta funzione hash ausiliaria.

Questo metodo è semplice, ma genera la stessa sequenza di ispezioni per le diverse con lo stesso .

Ispezione quadratica

dove è l'hash ausiliaria e sono costanti, con buoni valori e .

Anche in questo caso genera la stessa sequenza di ispezioni per diverse con uguali.

Doppio hashing

dove sono hash ausiliarie, di cui marca la cella di partenza mentre definisce lo step delle ispezioni.

Questo metodo genera sequenze diverse di ispezione, dato che dipendono da .

Per generare sequenze su tutti i valori della tabella, dev'essere relativamente primo con :

  • Si usa pari e si definisce come sempre dispari, e.g.
  • Si usa primo e minore di , e.g. , per

Tempo di ricerca

Al contrario del concatenamento, l'indice di prestazione perchè .

Se esiste almeno una cella vuota su cui la ricerca senza successo si può fermare, quindi:

  • perchè la prima ispezione è sempre effettuata
  • ovvero la probabilità che la cella su sia occupata
  • perchè anche la cella su sia occupata
  • perchè anche la cella su sia occupata

Di conseguenza il valore atteso di , ovvero il numero medio di ispezioni, è al massimo1: e lo stesso vale per l'inserimento, dato che cerca una cella vuota.

Nella ricerca con successo invece, il numero medio di ispezioni è .

1

CLRS, Introduction to Algorithms (4th ed.), pp. 298-299