Miskolci Egyetem Informatikai Intézet Általános Informatikai Tanszék Pance Miklós Adatstruktúrák, algoritmusok előadásvázlat Miskolc, 2004 Technikai közreműködő: Imre Mihály, műszaki informatikus hallgató
Feb 08, 2016
Miskolci EgyetemInformatikai Intézet
Általános Informatikai Tanszék
Pance MiklósAdatstruktúrák, algoritmusok
előadásvázlat
Miskolc, 2004
Technikai közreműködő: Imre Mihály, műszaki informatikus hallgató
Hash
(K-Key, A-Address), hashing – tördelő, az argumentum felvagdalására utal. Alapvetően új, egyszerű, gazdaságos, de vannak hátrányai is.
Kulcs tömbindex : kulcstranszformáció
Nehézség: a lehetséges kulcsértékek halmaza általában jóval nagyobb, mint a rendelkezésre álló tárolási címek halmaza.
Pl.: 26 betűs ABC, maximum 10 betűs kulcs, 1000 ember2610 103 ; a H így nyilvánvalóan nem egyértelmű
függvény, bizonyos kulcsokhoz azonos címet rendel.
2
AKH :
kHh és utána ellenőriz, hogy kkulcskHT .
Hash függvényekA H függvény megválasztásának szempontjai:
- a kulcsokat egyenletesen szórja szét az indextartományon,
- gyorsan lehessen kiszámítani.
1. Osztásos módszer:
Ha az ord(k) megadja a k kulcs sorszámát az összes lehetséges kulcsból álló halmazon, és az i tömbindex tartománya a [0..N-1] egész számok intervalluma:
3
NkordkH mod
Ez egyenletesen terít, gyakran alkalmazzák. Gyors, ha N kettő hatványa, de a kevés karakterben különböző szavak nagyobb valószínűséggel kapnak azonos indexet, nem egyenletes.
Hash függvényekTanácsosabb N-nek prímszámot választani: pl.
4
12 i
vagy 11 kkNkH 618033988.02
151
A [0, 1) intervallumon a fgv. alapja egyenletes eloszlású (Knuth).(Rendes osztást kell végezni!)
2. Középnégyzet módszer: k2 mindkét végéről törlünk kellő számú számjegyet,
pl. N=100, {00, …, 99}
k 3205 7148 2345k2 10272025 51093904 549925
H(k) 72 93 99
Hash függvények3. Hajtogatásos módszer:
a kulcsot k1, k2, k3, … részre osztjuk, az értékeket
összeadjuk, az elejét ha kell levágjuk; hossza a cím hossza, a páros sorszámú elem jegyeit megcserélhetjük: H(3205)=32+05=37 32+50=82 H(7148)=71+48=19 71+84=55 H(2345)=23+45=68 23+54=77
4. Logikai műveletre alapozott tördelő függvény:A 4 byte-os részstringeket logikai XOR-ral összeadjuk, az eredményt számként értelmezzük -> i és H(s) = i mod N.
5
Hash függvények5. Tökéletes (perfect) hashing
A H(k) függyvény egy-egy típusú leképezést valósít meg, azaz az előforduló kulcsokat egy kezelhető egész tartományra képezi le. Az H függvény a K-ra akkor és csak akkor tökéletes, ha j, k K ∀ ∈ H(j) = H(k) → j = k
6. Univerzális hashingEgy rosszindulatú ellenség mindíg tud olyan kulcsokat választani, hogy azok mindegyike ugyanarra a helyre képeződjék le, ami O(N) keresési időhöz vezet. Az univerzális hashing (Cormen) egy hash függvény-készletből véletlenszerűen választ.
6
Hash függvények7. Lineáris (sorrend megőrző) hash
Olyan H függvény, amely megtartja az input kulcsok sorrendjét, miközben megváltoztatja térközét:
k1, k2 ∈ K k1 > k2 → ∧ H(k1) > H(k2)
8. Dinamikus hash
A hash tábla növekszik, hogy egyre több elemet tudjon kezelni, miközben a hash függvénynek is változnia kell. Bizonyos sémák esetén a törléseket követően a tábla mérete csökkenhet is. (Speciális esete a bővíthető hash.)
7
Hash függvények9. Kakukk (cuckoo) hash
Két hash táblát: T1,T2 és két hash függvényt: H1,H2 használ.
Az egyes k kulcsok bármely táblában lehetnek: T1[H1(k)] vagy T2[H2(k)].
A k új kulcsot a T1[H1(k)] helyre tesszük. Ha ezt egy I kulcs már foglalja, akkor azt a T2[H2(l)] helyre tesszük és így tovább, míg üres helyet találunk, vagy elértünk egy korlátot. Ekkor új hash függvényt választunk és újraszámoljuk a táblát.
8
Hash függvények10. Minimális tökéletes (perfect) hash
Minden különböző kulcsot különböző egészre képez le és a lehetséges egészek száma ugyanaz, mint a kulcsoké. A H függvény akkor és csak akkor minimális tökéletes hash függvény a K kulcshalmazra nézve, ha
∀ j, k K∈ H(j) = H(k) → j = k a H(k) értékkészlete 1 .. |K|
Speciális esete a sorrend megőrző minimális tökéletes (perfect) hash.
9
Hashing alkalmazása- Compiler így tartja nyilván a deklarált változókat a
szimbólum táblában. A hashing ideális mivel a fordításhoz csak a beszúrás és a keresés műveletek szükségesek.
- Gráfok csúcspontjai nevének keresése.
- Játékok.
- Helyesírás (online) ellenőrzése. (Ha nem kell névsorban adni a hibákat.)
- Adatbáziskezelés, indexfájlok.
- Digitális aláírás.
10
Hash: ütközés kezeléseÜtközés: a hash tábla adott indexű eleme (slot, rés) már
foglalt.
Ütközés kezelése
1. Nyílt hash tábla
Az ugyanazon elsődleges indexhez tartozó elemeket felfűzzük egy láncolt listára (lista tömb). Közvetlen láncolás, ha a hash tábla csak címeket tartalmaz. A plusz tároló helyeket túlcsordulási területnek nevezzük (overflow area). A kétszeresen láncolt lista hatékonyabb.
Előnye: "korlátlan" számú elem és ütközés kezelhető.
Hátránya: a láncolt listával kapcsolatos többletmunka.
11
Hash: ütközés kezelése2. Fix túlcsordulási terület
A hash táblát elsődleges és túlcsordulási területre osztjuk és indexláncot képezünk. Probléma: a két terület arányának optimális megválasztása.
Előnye: gyors hozzáférés, az ütközések nem használják az elsődleges területet.
Nehézség: a tábla felosztási arányának előzetes meghatározása.
Továbbfejlesztés: többszörös túlcsordulási területek alkalmazása.
12
Hash: ütközés kezelése3. Nyílt címzés (open addressing)
Magában a hash táblában keres még nem foglalt helyet.h:= H(k) ; i:= 0;
repeat
IF T[h].kulcs = k THEN a tétel szerepel ELSE
IF T[h].kulcs = szabad THEN a tétel nem szerepel ELSE
begin
ütközés
i:= i+1; h:= H(k)+ G(i)
end;
until szerepel, nincs a táblában (vagy tele a tábla);
13
Hash: ütközés kezelése3.a. Lineáris pótvizsgálat (Morris)
14
kHh 0 Nihhi mod0 i = 1, ..., N-1
pl.: {89,18,49,58,69} (N=10, nem prímszám)Üres 89 18 49 58 69
0 49 49 49
1 58 58
2 69
345678 18 18 18 18
9 89 89 89 89 89
Hash: ütközés kezelése3.b. Négyzetes pótvizsgálat (Morris)
15
kHh 0 Nihhi mod20 i > 0
pl.: {89,18,49,58,69} Üres 89 18 49 58 69
0 49 49 49
12 58 58
3 69
45678 18 18 18 18
9 89 89 89 89 89
Hash négyzetes pótvizsgálatElőfordulhat, hogy nem derít fel minden szabad helyet a
táblában, de ha N prímszám, akkor mindíg használni tudja legalább a tábla felét.
Tegyük fel, hogy egy i-edik és egy j-edik pótvizsgálat a tábla ugyanazon helyéhez vezet:
16
)(mod 0modmod 2222 NjiNjNi
N mod 0 jiji
Mivel , ji
NCji , ezért i és j közül legalább az egyik nagyobb N/2-nél, hiszen
csak így teljesülhet valamilyen C természetes számra.
Hash négyzetes pótvizsgálat
A hash függvény számításának gyorsítására a négyzetre emelés helyett:
hi = i2 ; di = 2i+1 i = 1; h1 = 1; d1 = 3;
hi+1 =hi + di h2 = 4; d2 = 5;
di+1 =di + 2 (i > 0) h3 = 9; d3 = 7;
17
Hash: ütközés kezeléseBokrosodás (clustering)
A lineáris pótvizsgálat a bokrosodás jelenségétől szenved: az egy helyről induló újrahash-elések egy blokkot foglalnak el és a többi kulcsoknak megfelelő helyek felé nőnek. Ez fokozza az ütközésveszélyt és egyre több újrahash-elést eredményez.
A négyzetes pótvizsgálatnál a másodlagos bokrosodás kevésbé súlyos probléma, mint a lineárisnál.
A hash tábla telítettségével a többszörös ütközések egyre valószínűbbek.
18
Dupla hashingG(i) = i H2(k); H2 –t is jól kell megválasztani, nem adhat
zérust. A bokrosodás esélye minimális.
Pl. H2(k)=R-(k mod R) R < N prímszám
19
Üres 89 18 49 58 690 69
123 58 58
456 49 49 49
78 18 18 18 18
9 89 89 89 89 89
Pl.: R=7
H2(49)
=7-0=7
H2(58)
=7-2=5
H2(69)
=7-6=1
RehashingHa a tábla túlságosan telített, a futási idő egyre nő és a
beszúrás nem sikerül.
Megoldás: felépítünk egy kétszer akkora táblát, az eredetiből átvisszük a még érvényes bejegyzéseket.
Pl.: {13, 15, 24, 6}; N=7; H(k)=k mod 7, lineáris pótvizsgálat
20
0 1 2 3 4 5 66 15 23 24 13
Az új tábla mérete: 17 (a következő kétszeres prímszám).Rehashing, ha pl. a tábla félig telt; vagy a beszúrás nem sikerült, vagy fáradságos; vagy a tábla valamilyen %-ig telt (telítettségi tényező).
Bővíthető hashingAz egész tábla nem fér a központi memóriába, így lényeges a
disk hozzásférések (műveletek) száma. A nyílt vagy a zárt hashing esetén számos blokkot meg kell vizsgálni. A bővíthető (extendible) hashing lehetővé teszi, hogy a keresés 2 diszk művelettel megoldható legyen. Pl. M=4
21
00 01 10 11
(2)
000100001000001010001011
(2)
010100011000
(2)
100000101000101100101110
(2)
111000111001
Bővíthető hashingAz 100100 beszúrásához , a 3. tele van, ezért kettévágjuk és
az első 3 bit lesz a meghatározó, a directory mérete 3 lesz, a teljes directory-t átírjuk.
22
000 001 010 011 100 101 110 111
(2)
000100001000001010001011
(2)
010100011000
(3)
100000100100
(3)
101000101100101110
Előfordul, hogy nagyobbat kell ugrani, pl. 2-ről 4-re:Pl.: D=2; 111010, 111011, 111100 beszúrása után már csak az első 4 bit tud különbséget tenni.Nem lehet M -nél több azonos kulcs.
(2)
111000111001
Hashing: törlés Legcélszerűbb megoldás: a törölni szándékozott elem
bejegyzését nem töröljük, csak törlésre jelöljük, így a keresés, beszúrás változatlan módon folytatható.
23