Föreläsning 18 Sply-träd, hshning, skip-listor TDDD86: DAL Utskriftsversion v föreläsning i Dtstrukturer, lgoritmer oh progrmmeringsprdigm 11 novemer 2015 Tommy Färnqvist, IDA, Linköpings universitet 18.1 Innehåll Innehåll 1 Sply-träd 1 2 Hshteller 7 2.1 Kollisionshntering...................................... 7 2.2 Att välj hshfunktion..................................... 10 3 Skip-listor 12 18.2 1 Sply-träd Binär sökträd är inte unik Kom ihåg det inär sökträdet: Enkelt tt sätt in oh t ort element, men... lnsen estäms v ordningen på insättningr oh orttgningr. Kominer med heuristiken håll nyligen nvänd element först för listor? Oft nvänd element ör finns när roten! insert: 1,2,4,5,8 insert: 5,2,1,4,8 18.3 Opertionen sply(k) Utför en norml sökning efter k, kom ihåg nodern vi psserr... Märk den sist noden vi undersöker med Om k finns i T, finns k i noden, nnrs är förälder till ett tomt träd Återvänd till roten oh gör en rottion vid vrje nod för tt flytt uppåt i trädet... (3 fll) 18.4 1
Opertionen sply(k) zig: prent() är roten: roter kring 18.5 Opertionen sply(k) zig-zig: oh prent() är ägge vänsterrn (eller ägge högerrn): utför två rottioner för tt flytt upp d R R d R d 18.6 Opertionen sply(k) zig-zg: En v oh prent() är ett vänsterrn oh den ndr är ett högerrn eller vie vers: utför två rottioner i olik riktningr R d d R Oserver tt dess rottioner kn ök trädets höjd! 18.7 2
find oh insert funtion FIND(k, T ) SLAY(k,T ) if KEY(ROOT(T )) = k then return (k, v) else return null funtion INSERT(k, v, T ) sätt in (k,v) som i ett inärt sökträd SLAY(k,T ) 18.8 Exempel: insättning v 14 18.9 Exempel: insättning v 14 18.10 Exempel: insättning v 14 3
18.11 Exempel: insättning v 14 18.12 Exempel: insättning v 14 4
18.13 Exempel: insättning v 14 18.14 delete funtion DELETE(k, T ) if k finns i ett löv then gör SLAY på föräldern till lövet else if k finns i en intern nod then ersätt noden med dess föregångre i inorder gör SLAY på föräldern till föregångren Det går förstås tt nvänd efterföljren i inorder okså. 18.15 Exempel: orttgning v 8 5
18.16 Exempel: orttgning v 8 18.17 Exempel: orttgning v 8 6
18.18 restnd Vrje opertion kn ehöv utförs på ett totlt olnsert träd lltså ingen grnti för tid O(logn) i värst fllet Amorterde tiden är logritmisk vrje sekvens v m opertioner, utförd på ett initilt tomt träd, tr totlt O(mlogm) tid lltså är den morterde kostnden/tiden för en opertion O(logn) även om enskild opertioner kn ete sig myket värre 18.19 2 Hshteller Kn vi hitt på något ättre? J, med hjälp v hshteller Idé: givet en tell T [0,...,mx] tt lgr element i...... hitt ett lämpligt tellindex för vrje element Hitt en funktion h sådn tt h(key) [0,...,mx] oh (idelt) sådn tt k 1 k 2 h(k 1 ) h(k 2 ) Lgr vrje nykel-värdepr (k,v) i T [h(k)] 18.20 Hshtell I prktiken ger inte hshfunktioner unik värden (de är inte injektiv) Vi ehöver kollisionshntering... oh Vi ehöver hitt en r hshfunktion 18.21 2.1 Kollisionshntering Kollisionshntering Två priniper för tt hnter kollisioner: Länkning: håll kroknde dt i länkde listor Seprt länkning: h de länkde listorn utnför tellen Smld länkning: lgr ll dt i tellen Öppen dressering: lgr ll dt i tellen oh låt någon lgoritm estämm vilket index som sk nvänds vid en kollision [Eng: Seprte Chining, Colesed Chining, Open Addressing] 18.22 7
Exempel: hshning med seprt länkning Hshtell med storlek 13 Hshfunktion h med h(k) = k mod 13 Lgr 10 heltlsnyklr: 54, 10, 18, 25, 28, 41, 38, 36, 12, 90 0 1 2 41 28 54 3 4 5 6 18 7 8 9 10 36 10 11 12 90 12 38 25 18.23 Seprt länkning: find Givet: nykel k, hshtell T, hshfunktion h eräkn h(k) let efter k i listn T [h(k)] pekr ut Nottion: sondering= en ess i den länkde listn 1 sondering för tt komm åt listhuvudet (om ike-tomt) 1+1 sondering för tt komm åt innehållet i först listelementet 1+2 sondering för tt komm åt innehållet i ndr listelementet... En sondering (tt följ en pekre) tr konstnt tid. Hur mång vpekningr ehövs för tt hämt en post i hshtellen? 18.24 Seprt länkning: misslykd uppslgning n dtelement m pltser i tellen Värst fllet: ll dtelement hr smm hshvärde: = 1 + n Medelfllet: hshvärden likformigt fördelde över m: medellängd α v list: α = n/m = 1 + α 18.25 Seprt länkning: lykd uppslgning Medelfllet: ess v T [h(k)] (örjn v en list L): 1 trverser L k hitts efter: L /2 förväntt L svrr mot α, lltså: förväntt = α/2 + 1 18.26 Smld länkning: ehåll elementen i tellen ler dtelementen i tellen Utök dem med pekre Lös kollisioner genom tt nvänd först ledig plts Kedjor kn innehåll nyklr med olik hshvärden...... men ll nyklr med smm hshvärden dyker upp i smm kedj + Bättre minnesnvändning - Tellen kn li full - Längre kollisionskedjor 18.27 8
Smld länkning 18.28 Öppen dressering Lgr ll element inuti tellen Använd en fix lgoritm för tt hitt en ledig plts Sekvensiell/linjär sondering önskvärt hshindex j = h(k) om konflikt uppstår gå till näst ledig position om tellen tr slut, gå till örjn v tellen... ositioner i närheten v vrndr fylls snt upp (primärklustring) Hur gör mn remove(k)? 18.29 Öppen dressering remove() Elementet som sk ts ort kn vr del i en kollisionskedj kn vi vgör det? Om det är del v en kedj kn vi inte r t ort elementet! Eftersom ll nyklr lgrs, hsh om ll dt som är kvr? Titt lnd elementen efter, hsh om eller dr ihop när lämpligt, stnn vid först ledig position...? Ignorer sätt in en mrkör orttgen (deleted) om näst plts är ike-tom... 18.30 Duel hshning eller vd gör vid kollision? Andr hshfunktion h 2 eräknr inkrement i fll v konflikter Inkrement utnför tellen ts modulo m = tlesize Linjär sondering är duel hshning med h 2 (k) = 1 Krv på h 2 : h 2 (k) 0 för ll k h 2 (k) hr ing gemensmm delre med m för något k ll tellpositioner kn nås Ett vnligt vl h 2 (k) = q (k mod q) för q < m, m primtl (dvs, välj ett primtl mindre än tellstorleken!) 18.31 9
2.2 Att välj hshfunktion Vd är en r hshfunktion? Antg tt k är ett nturligt tl. Hshning ör ge en likformig fördelning v hshvärden, men dett eror på distriutionen v nyklr i dtt som sk hshs. Exempel: Hshning v efternmn i en (svensk) grupp studenter hshfunktion: ASCII-värdet v sist okstven dåligt vl: mjoriteten v nmn slutr med n. 18.32 Stränghshning i Jv hshcode() för String i Jv 1.1 För lång strängr: undersök r 8-9 jämnt utspridd teken. Fördel: sprr tid Nkdel: stor potentil för dålig kollisionsmönster 18.33 Förslg på hshfunktioner Minnesdressen Tolk minnesdressen där ojektet som sk hshs finns som ett heltl Fungerr r i llmänhet, men inte r för t.ex. numerisk nyklr eller strängnyklr. Omvndl till heltl Tolk om itrn i nykeln som ett heltl Lämpr sig för nyklr v kortre längd än ntlet itr i heltlstypen Komponentsumm Del upp itrn i nykeln i komponenter v fix längd (t.ex 16 eller 32 itr) oh summer komponentern. (Ignorer overflow.) Lämpr sig för numerisk nyklr v fix längd större än eller lik med ntlet itr i heltlstypen. 18.34 Förslg på hshfunktioner olynomisk kumulering Del upp itrn i nykeln i en sekvens v komponenter v fix längd (t.ex. 8, 16 eller 32 itr) Evluer polynomet vid ett fixt värde z. (Ignorer overflow.) 0 1 n 1 p(z) = 0 + 1 z + 2 z 2 +... + n 1 z n 1 Extr lämpligt för hshning v strängr. (T.ex. z = 33 ger som mest 6 kollisioner på en mängd v 50000 engelsk ord.) olynom p(z) kn evluers i O(n) tid genom tt nvänd Horners regel: Följnde polynom eräkns suessivt. Vrje polynom i sekvensen kn eräkns i O(1) tid utgående från föregående polynom i sekvensen p 0 (z) = n 1 p i (z) = n i 1 + zp i 1 (z) (i = 1,2,...,n 1) Vi hr p(z) = p n 1 (z) 18.35 10
Stränghshning i Jv hshcode() för String i Jv numer 18.36 Algoritmisk komplexitetsttker Spelr ntgndet om uniform fördelning v nyklr tt sätt in någon roll i prktiken? Uppenr situtioner: flygledning, kärnkrftverk, pemker Överrsknde situtioner: denil-of-servie-ttker Verklig ttkmöjligheter [Crosy-Wllh 2003] Bro server: skik noggrnnt utvld pket för tt DOS-ttker servern med mindre ndredd än ett uppringt modem. erl 5.8.0: sätt in noggrnnt utvld strängr i ssoitiv rry. Linux 2.4.20-kärn: spr filer med noggrnnt utvld nmn. 18.37 Algoritmisk komplexitetsttk mot Jv Mål: Hitt fmilj v strängr med smm hshvärde Lösning: Jvs sträng-ai nvänder s 31-koden för stränghshning 18.38 Hshning genom heltlsdivision Låt m vr tellstorleken Undvik m = 2 d : hshning ger sist d itrn i k m = 10 d : hshning ger d sist siffrorn h(k) = k mod m Mn rukr föreslå primtl för m Undersök stikprov från riktig dt för tt experimenter med hshprmetrrn Se http://urtleurtle.net/o/hsh/doos.html för ndr åsikter i frågn. 18.39 11
3 Skip-listor Skip-listor En hierrkisk länkd list... Ett rndomisert lterntiv för implementtion v ADT Ditionry Insättning nvänder rndomisering ( slntsingling ) Br prestnd i det förväntde fllet Värstfllsprestnd i skip-listor inträffr väldigt sälln (>250 dtelement, risken tt söktiden är mer än 3 ggr den förväntde är under 10 6 ) 18.40 Dtstrukturen skip-list Nivåer L 1,...,L h v noder (nyklr, värden) Smm noder finns på fler nivåer (torn) Speiell nyklr: oh +... mindre/större än vrje riktig nykel... Fler nivåer v duellänkde listor, glesre högre upp Nivå 1: ll noder i en duellänkd list melln oh + ordnde enligt < -reltionen I medeltl finns hälften v nodern i L i okså i L i+1 Speiell nyklr oh + finns på ll nivåer Br oh + finns på nivå L h 18.41 Exempel: en skip-list 18.42 Sökning Sökning efter nykel k: Följ listn på högst nivån... Stnn innn vi psserr något k i > k (vi riskerr tt miss det vi letr efter) Om vi hittt rätt, returner det, nnrs... Vi hr stnnt på en nivå: Hr vi hittt nykeln? Nej, yt till näst lägre nivå (vi sist tornet ) oh fortsätt let Returnerr: störst nykeln k i k (vilket kn vr + ) 18.43 Sökning Sökning efter nykel k: Likheter med inärsökning men för listor Exempel: find(18) 12
18.44 Insättning funtion INSERT(x) FIND(x) if.vlue < x then sätt in en ny listnod efter singl slnt för tt vgör hur högt tornet sk vr: while slntsingling =j do ök tornets höjd ett steg (ök möjligtvis höjden på skip-listn) 18.45 Exempel: insert(20) 18.46 Borttgning... oh egenskper Väldigt likt insert: Sök om hittt, t ort oh fix länkrn melln tornen Värstfllstiden för find, insert oh remove i en skip-list med n instt element är O(n + h) Men förväntd exekveringstid (under ntgndet tt nyklrn är likformigt fördelde) är O(logn) om sökningen strtr på höjd logn 18.47 13