Hash table: differenze tra le versioni
Contenuto cancellato Contenuto aggiunto
(21 versioni intermedie di 14 utenti non mostrate) | |||
Riga 6:
{{F|programmazione|febbraio 2013}}
In [[informatica]]
Esistono vari tipi di algoritmi di hashing. Per quanto affermato, in una tabella di hashing ben dimensionata il costo medio di ricerca di ogni elemento è indipendente dal numero di elementi. L'hashing è un problema classico dell'informatica; molti algoritmi sono stati proposti, studiati a fondo e impiegati in pratica. Due metodi molto diffusi sono l'hashing statico e l'hashing estendibile e lineare, metodi utilizzati anche dai
== Descrizione ==
=== Funzionamento e implementazione === Il primo passo per realizzare algoritmi di ricerca tramite hashing è quello di determinare la ''funzione di hash'': il dato da indicizzare viene trasformato da un'apposita [[funzione di
<math>h
Idealmente, chiavi diverse dovrebbero essere trasformate in indirizzi differenti, ma poiché non esiste la funzione di
Molto spesso però, una buona funzione di hash può non bastare: infatti le prestazioni di una ''hash table'' sono fortemente legate anche al cosiddetto fattore di carico (''load factor'') calcolato come
:<math>\frac\text{cardinalità insieme di chiavi da inserire}\text{dimensione massima della struttura}</math>
==Gestione delle collisioni==▼
e che dice quanta probabilità ha un nuovo elemento di collidere con uno già presente nella tabella. Questa probabilità, in realtà, è più alta di quanto si possa pensare, come dimostra il [[paradosso del compleanno]]. È bene dunque mantenere il load factor il più basso possibile (di solito un valore di {{Formatnum:0,75}} è quello ottimale) per ridurre al minimo il numero di collisioni. Ciò può essere fatto, ad esempio, ridimensionando l'array ogni volta che si supera il ''load factor'' desiderato.
▲=== Gestione delle collisioni ===
Di seguito vengono riportati i metodi più diffusi per la gestione delle collisioni.
* '''Open Hash''' (o indirizzamento aperto)
* '''Hash con concatenazione''' (o con lista di trabocco)
== Open Hash ==
Nell
Diversamente dal concatenamento, non ci sono liste né elementi memorizzati all'esterno della tavola. Quindi nell'indirizzamento aperto, la tavola hash può "riempirsi" al punto tale che non possono essere effettuati altri inserimenti.
Il vantaggio dell'indirizzamento aperto sta nel fatto che esclude completamente i puntatori, ''calcoliamo'' la sequenza delle celle da esaminare (
Un concetto importante al riguardo è il cosiddetto hashing uniforme'''
Esistono diverse tecniche di ispezione, le tre tecniche più comunemente utilizzate sono: ispezione lineare, ispezione quadratica e doppio hashing. Tuttavia, nessuna di queste tecniche soddisfa l'ipotesi di hashing uniforme, in quanto nessuna di esse è in grado di generare più di <math>m^2</math> sequenze di ispezione differenti (anziché <math>m!</math>, come richiede l'hashing uniforme).
Riga 46 ⟶ 50:
Quando si incontra una collisione non si fa altro che utilizzare l'indice successivo a quello che collide, sino a che non si trovi una casella libera.
<math>h(k,i) = (h^1 (k) + c_1 i + c_2 i^2)\pmod{m}</math>
Quando si incontra una collisione non si fa altro che utilizzare l'indice che collide elevato al quadrato con normalizzazione rispetto alla grandezza della tabella dell'indice ottenuto, sino a che non si trovi una casella libera.
<math>h(k,i) = (h_1 (k) + i h_2 (k))\pmod{m}</math> dove, per esempio possiamo porre <math>h_1 (k) = k \pmod{m}</math> e <math>h_2 (k) = 1 + (k \pmod{m^1})</math>.
Riga 58 ⟶ 62:
== Hashing statico ==
Nell'hashing statico si utilizza il concetto di bucket, che è l'insieme di pagine contenenti le etichette dei record di dati.
Se una pagina bucket primaria è piena, viene creata una pagina di overflow. Per cercare l'etichetta corrispondente alla chiave <math>k</math> (<math>M =</math> numero di bucket) si utilizza la seguente formula di
<math>h(k) = \mbox{bucket}</math> a cui appartiene l'etichetta.
La funzione di hash <math>h</math> agisce sul campo della chiave di ricerca del record <math>r</math> e deve distribuire i valori su <math>0,...,M-1</math> (<math>M</math> bucket). Le prestazioni della ricerca dipendono molto dalla funzione <math>h</math>.
Riga 72 ⟶ 76:
Nell'hashing estendibile si parla di profondità di directory e si intende il numero minimo di bit che permette di rappresentare il numero di elementi contenuti nella directory.
== Hashing lineare ==
L'hashing lineare, come accennato nel paragrafo precedente, permette di risolvere il problema delle lunghe catene di overflow senza l'utilizzo delle directory.
L'idea di base è quella di utilizzare una famiglia di funzioni hash <math>h_0,h_1,... h_n</math> dove <math>h_i</math> ha un range che è la metà di quello di <math>h_i+1</math>. Questo vuol dire che il range di <math>h_1</math> è <math>2^1 N</math>
Riga 105 ⟶ 109:
|}
dove
==Bibliografia==
Riga 114 ⟶ 118:
==Altri progetti==
{{interprogetto|preposizione=sull'}}
== Collegamenti esterni ==
* {{Collegamenti esterni}}
* {{FOLDOC|hash coding|hash coding}}
* {{Cita web|url=http://didawiki.di.unipi.it/lib/exe/fetch.php/informatica/all-b/hash.pdf|titolo=Note su tabelle hash|cognome=Luccio|nome=Fabrizio|wkautore=Fabrizio Luccio|lingua=italiano|formato=pdf|accesso=20 giugno 2017}}
{{strutture dati}}
{{Controllo di autorità}}
{{Portale|informatica}}
|