Hashing / Hash tabeller -- Kapitel 20
Hash? Varför en annan datastruktur? Konstant tid för både insert- och find- operationer
Hash? Insert ”Daniel” =18 Find
Hashfunktioner! Hash functioner använder associerade “key” ( som kan vara data i sig ) för att få fram datan. Hash funktionerna är olika för olika sorts data. Integers Images Strings Etc…
Hashing integers? Tänk 16bit int => 0 – Skapa int[] vec = new int[65536]; Add i => vec[i]++; Sök value j => Is vec[j] > 0? Ta bort value k => vec[k]--; Men för en... Java int : 32bit 44 billion items => impractical!
Exempel av hash funktion D D a a n n i i e e l l ”Daniel” = 589
Men... Hur unik är den? hashfunc(”Daniel”) → 589 hashfunc(”leinaD”) → 589 Bättre lösning men….! hashfunc(”TestValue”) → Wrapp värdet till ett visst intervall Vilken? Arraystorleken…
En bättre hash funktion Ett bättre sätt att beräkna hash värdet Om vi har en text sträng av längd n+1 och alla tecken har index A n, A n-1,...,A 0 gör s = A n X n + A n-1 X n A 0 X 0 = = ((A n )X + A n-1 )X A 0 Använd hashValue = s % array.length
Och då For example: ”Danne” (((’D’)128 + ’a’)128 + ’n’)128 + ’n’)128 + ’e’ = (((68) ) ) ) = hashValue = % array.length om length = 7919 (prim nummer) => hashValue = % 7919 = 2690
Hur löser man kollision? Oavsätt hur unika keys en hash- funktionen tar fram, kollision alltid inträffas. Terminology Load factor
Lösningar Linear probing ( undersökning ??) Quadratic probing Double hashing Separate chaining
Linear probing Sök fram till näst lediga platsen. hashfunc ( ) X=18X+1,X+2,X+3,X+4,X+5,...
Linear probing Fenomen kallat: Primary clusters
Linear probing Bygger upp kluster Påverkar exekveringstiden för insert () och find()!
Quadratic probing Försök undvika“primary clusters “ Snabare en linjär Kvadratisk inkrementation av undersökning avståndet X=18X+1 2,X+2 2,X+3 2,X+4 2,X+5 2,...
Quadratic probing Garantera att hitta fria platser om de finns 1 2 = 12 2 = 43 2 = 9
Double hashing Använder en till hash funktion för att hitta fri plats. X = hash(obj); X2 = hash2(obj); X=18, X2=7X+1*X2,X+2*X2,X+3*X2,X+4*X2,... X=18, X2=718+1*7,18+2*7,17+3*7,18+4*7,...
Double hash probing 1*3= 32*3= 63*3 = 9 Hash2() = 3 Andra hash-funktionene Får inte returnera 0!
Separate chaining Varje hash position har en länkad lista. Påverkar inte andra värde, probing görs bara i listan. Varje element I tabellen är en länkad lista.
Separate chaining H H H H H H H H H H H H H H H H H H Insert
Jämförelse Linear probing Enkel Kan resultera i linjär söktid Quadratic probing Kräver Load factor < 0.5 annars rehashing ?? Kräver prim tal för array storleken Separate chaining LF < 1 Ingen dubblering, länkade listor är dinamiska ! Kan leda till linjär sökning men I verklighetet ganska kort Double hash probing Eliminerar kluster
Implementation Quadratic prob.... Object[] list = new Object[size]; // Prime length... int hash(Object o) { int start= Math.abs(o.hashCode() % list.length); int quadNbr = 0; int index = start; while(list[index] != null) { index = start + Math.pow(++quadNbr, 2); } return pos; }