TDDI16 Datastrukturer och algoritmer Prioritetsköer, heapar, Union/Find
Prioritetsköer En vanligt förekommande situation: Väntelista (jobbhantering på skrivare, simulering av händelser) Om en resurs blir ledig, välj nästa element från väntelistan Valet är baserat på någon partiell ordning, t.ex.: Jobbet med högst prioritet ska köras först Varje händelse ska inträffa vid en viss tidpunkt; händelserna ska bearbetas i tidsordning
ADT prioritetskö (PQ) Linjärt ordnad mängd K av nycklar Vi lagrar par (k, v) (som i ADT Dictionary) Flera par med samma nyckel är tillåtet En vanlig operation är att hämta paret med minsta nyckel
TDDI16 Datastrukturer och algoritmer 2017-09-26 4 Operationer på en prioritetskö P makeemptypq() isempty() size() min(): hitta och returnera ett par (k, v) som har minimalt k insert(k, v): sätt in (k, v) i P removemin(): ta bort och returnera ett par (k, v) i P med minimalt k ; error om P är tom
Implementation av prioritetsköer Vi kan t.ex. använda (sorterade) länkade listor, eller BST En annan idé: använd ett fullständigt binärt träd där roten i varje (del)träd T innehåller det minsta elementet i T Räcker med partiell ordning
Ett fullständigt binärt träd i naturen
TDDI16 Datastrukturer och algoritmer 2017-09-26 7 Heap Det här är ett partiellt ordnat fullständigt träd, också kallat heap
Heapvarianter Olika partialordningar Minsta nyckeln i roten (min-heap) Största nyckeln i roten (max-heap)
Höjden av en heap En heap som lagrar n nycklar har höjd O(log n) Bevis: Låt h vara höjden av en heap som lagrar n nycklar
Höjden av en heap (forts) Det finns 2 i nycklar på djup i = 0,... h 1 och minst en nyckel på djup h Således n 1 + 2 + 4 +... + 2 h 1 + 1 djup nycklar 0 1 2 h 1 1 Alltså är n 2 h, dvs. h log n 1 h-1 h 2 2 h-1 1
Att uppdatera en heapstruktur sista lövet = sista noden i en traversering i levelorder (högraste noden på lägsta höjden) removemin(pq) // ta bort roten Ersätt roten med sista lövet Återställ den partiella ordningen genom att byta noder nedåt: sift-down ( down-heap bubbling ) insert(pq, k, v) Sätt in ny nod (k, v) efter sista lövet Återställ den partiella ordningen genom sift-up ( upheap bubbling )
Insättning i en heap Metoden insert av nyckel k i heapen Lagra k efter sista lövet Sift up: Återställ heapegenskapen (rekursivt) 9 5 5 7 2 z 9 7 z 1 2 6 nytt sista löv 6
Sift up Efter insättning av ny nyckel k är det inte säkert att heapegenskapen fortfarande är uppfylld siftup: byt k längs uppåtgående stig från insättningsnoden 2 9 7 z 6 9 7 z 6
Sift up (forts) siftup terminerar vid roten eller en nod vars förälder k (för min-heap) Eftersom en heap har höjd O(log n) går siftup i tid O(log n) 2 9 7 z 6 9 7 z 6
Borttagning från en heap removemin för ADT priokö Impl. som borttagning i min-heap 1. Byt nyckeln i rot med nyckeln i det sista lövet w 2. Ta bort w 3. Återställ heapegenskapen (sift down) 9 9 5 7 5 w 2 6 sista lövet 7 6 w nytt sista löv
Sift down siftdown återställer heapegenskapen genom att byta w längs nedåtgående stig terminerar när w når ett löv eller om barnen w Eftersom en heap har höjd O(log n) går siftdown i tid O(log n) 9 5 6 w 9 7 w 6
Komplexitet för heap size(), isempty(), min(): O(1) insert(), removemin(): O(log n) Kom ihåg arrayrepresentationen av BST förutsätter fullständigt binärt träd Kompakt arrayrepresentation Sift up och sift down har snabba implementationer (med tillväxt O(log n))
Exempel: sift up efter insert(4,15) p(m) = m 1 2
Slå ihop två heapar 3 2 Givet två heapar och ny nyckel k 8 5 4 6 Skapa en ny heap där roten = k och med de två givna heaparna som delträd 8 3 5 7 4 2 6 Kör siftdown för att återställa heapegenskapen 8 3 5 2 7 4 6
Nybygge av heap: buildheap
TDDI16 Datastrukturer och algoritmer 2017-09-26 21 Två möjliga sätt Sämre alternativ Skapa heap av ett element Lägg till ett element i taget: insert(k) Heapify efter varje Bättre alternativ Skapa många små heapar Slå ihop Siftdown efter varje (billigare!)
Exempel: Konstruktion av heap bottenupp (min-heap) 10 7 8 25 5 11 27 16 15 4 12 6 7 23 20 16 15 4 12 6 7 23 20 25 5 11 27 16 15 4 12 6 7 23 20
Exempel: Konstruktion av heap bottenupp (min-heap) 10 7 8 25 5 11 27 16 15 4 12 6 7 23 20 25 5 11 27 16 15 4 12 6 9 23 20 15 4 6 20 16 25 5 12 11 9 23 27
Exempel: Konstruktion av heap bottenupp (min-heap) 10 7 8 25 5 11 27 16 15 4 12 6 7 23 20 7 8 15 4 6 20 16 25 5 12 11 9 23 27 4 6 15 5 8 20 16 25 7 12 11 9 23 27
Exempel: Konstruktion av heap bottenupp (min-heap) 10 7 8 25 5 11 27 16 15 4 12 6 7 23 20 10 4 6 15 5 8 20 16 25 7 12 11 9 23 27 4 5 6 15 7 8 20 16 25 10 12 11 9 23 27
Analys av värstafallstid För 16 löven ingen siftdown För 8 noder: max ett steg siftdown n 2 +,-, h = 5; n 32 = 1 n 2 +,-, h = 4; n 16 = 2 n 2 +,-, h = 2; n 8 = 4 n 2 +,-, h = 1; n 4 = 8 n 2 +,-, h = 0; n 2 = 16
Analys av värstafallstid 8 n 2 0 + n 4 1 + n 8 2 + + n 32 h n 2 +,-, h = 5; n 32 = 1 n 2 +,-, h = 4; n 16 = 2 n 2 +,-, h = 2; n 8 = 4 n 2 +,-, h = 1; n 4 = 8 n 2 +,-, h = 0; n 2 = 16 Max längd på varje siftdown för noder på denna höjd
Analys av värstafallstid =>? @ =>? @ 8 n 2 +,- h = n 8 h 1 +AB +AB 2 +,- =>? @ = n 2 8 h 1 2 + +AB =>? @ = n 2 8 h 1 2 +AB +
Analys av värstafallstid Deriv. formeln för geom.serier: =>? @ =>? @ 8 n 2 +,- h = n 8 h 1 +AB +AB 2 +,- H 8 kx E = EAB =>? @ = n 2 8 h 1 2 + +AB x (1 x) F, x < 1 =>? @ = n 2 8 h 1 2 +AB +
Analys av värstafallstid Deriv. formeln för geom.serier: =>? @ =>? @ 8 n 2 +,- h = n 8 h 1 +AB n 2 +AB 1J 2 1 1J F = n 2 2 2 +,- 1J 2 1J 4 H 8 kx E = EAB =>? @ = n 2 8 h 1 2 + +AB = n 2 2 O(n) x (1 x) F, x < 1 =>? @ = n 2 8 h 1 2 +AB +
Analys av värstafallstid (alternativ) siftdown efter sammanslagning: t.ex. en stig som först går till höger och sedan upprepade gånger går till vänster till botten av heapen
Analys (alternativ) Eftersom varje nod traverseras som mest av två sådana stigar är den totala stiglängden O(n)
Analys Alltså är tiden för att konstruera en heap botten-upp O(n) Den här konstruktionsmetoden är snabbare än n upprepade insättningar (med individuella siftup:s)
Union/Find
Partitioneringar med Union/Find-operationer makeset(x): Skapa en mängd enbart innehållande elementet x union(a, B): Returnera mängden A B, förstör de gamla A och B find(p): Returnera mängden som innehåller position p (p pekare el. index till ett element i mängden)
Exempel: Dynamisk konnektivitet Finns det en stig mellan p och q?
Exempel: Dynamisk konnektivitet Pixlar i ett digitalt foto Datorer i ett nätverk Vänner i ett socialt nätverk Transistorer på ett datorchip Element i en matematisk mängd
Trädbaserad implementation Använd parent-pointer tree (pekarna går åt fel håll) Varje element lagras i en nod som innehåller en pekare till omslutande mängd 1 2 5 4 7 3 6 8 10 9 11 12
Trädbaserad implementation Null-pekare eller självpekare för största omslutande mängd (roten) Varje mängd är ett träd, rotat i en nod med själrefererande pekare (eller null-pekare) 1 2 5 4 7 3 6 8 10 9 11 12
Operationer union: låt roten av det mindre trädet peka på roten av det större find (hitta omslutande mängd), följ förälderpekarna från startnoden till roten 3 3 2 9 2 9 6 6 8 11 8 11 5 10 12 5 10 12
Viktad union Låt roten i det mindre trädet T 1 peka på roten i det större trädet T 2 Mindre: T 1 T 2 Resulterande trädet T kan då hållas max log(n) djupt 3 2 9 6 11 8 5 12 10
Viktad union För varje union ökar träddjupet med 1 Samtidigt ökar antal element med minst faktor 2: T 1 + T 2 2 T 1 Djup i ger T = 2i element 3 2 9 6 11 8 5 12 10
Stigkomprimering Efter find flytta alla pekare på stigen som precis traverserats så att de alla pekar på roten Ger Θ(n log n) tid för att utföra n union- och findoperationer 5 5 8 10 8 10 11 11 2 12 2 12 3 6 3 6 9 9
TDDI16 Datastrukturer och algoritmer 2017-09-26 44 Itererade logaritmen log* n Antal ggr log måste tillämpas, tills värdet 1 Väldigt låg tillväxt n log* n ], 1] 0 ]1, 2] 1 ]2, 4] 2 ]4, 16] 3 ]16, 65536] 4 ]65536, 2 65536 ] 5 1 1 log 2 1 log log 4 1 log(log log 16 ) 1 log(log(log log 65536 )) 1
Nästa gång: Jämförelsebaserad sortering www.liu.se