La maggior parte delle implementazioni della tabella hash garantiscono O (1) caso medio ma O (n) valore massimo per la ricerca (dove 'n' è il numero di chiavi nella tabella). Ma Cuckoo Hashing è descritto come O (1) massimo. Apparentemente questo lo raggiunge usando due funzioni di hash, e se ottiene una collisione con una, usa quella alternativa. Se ottiene collisioni con entrambi, tenta prima di rimescolare gli oggetti per creare spazio, ma se ci sono tre chiavi che hanno tutte lo stesso valore con entrambe le funzioni hash, questo fallirà.
A quanto ho capito, il prossimo approccio è quello di cambiare le funzioni di hash.
In un'implementazione di tipo generico (ad es. questa implementazione di Haskell ) il modo ovvio per fare ciò è fornire un'interfaccia che permetta di fornire una famiglia di funzioni hash, in questo caso la classe Hashable
, che contiene una funzione hashWithSalt :: Int -> a -> Int
(dove a
è il tipo di hash ). Tuttavia, questo fornisce solo un singolo parametro Int
e un singolo output Int
, che è 32 bit * 2 = 64 bit di hash e sale possibili, quindi con qualsiasi valore contenente più dati di 65 bit ci sarà ancora un potenziale elementi che sempre si scontrano. In un caso peggiore teorico (ad es. come generato usando questo codice che sembra certamente mostrare O (1) tempi di ricerca almeno per n < = 50 - al di sopra di questo, il tempo di inserimento diventa problematico per qualche motivo) potrebbero esserci "n" elementi che entrano in collisione con tutte le potenziali funzioni di hashing.
In che modo, quindi, è possibile che la massima complessità della ricerca sia O (1)? C'è qualche trucco di implementazione che non ho afferrato che eviti questo problema?