Pˇri pr´aci s daty z uspoˇr´adan´eho univerza je ˇcasto tˇreba pracovat s dalˇs´ımi operacemi zaloˇzen´ymi na uspoˇr´ad´an´ı. Pˇr´ıkladem takov´ych ´uloh jsou grafov´e algoritmy. ˇC´asteˇcnˇe to umoˇzˇnuj´ı bin´arn´ı vyhled´avac´ı stromy nebo (a, b)-stromy a tak´e haldy. Haldy jsou velmi jednoduch´e, a proto jsou nˇekolikr´at rychlejˇs´ı neˇz bin´arn´ı vyhled´avac´ı stromy nebo (a, b)- stromy. Cena za to je, ˇze haldy nepodporuj´ı operaci MEMBER. Dalˇs´ı nev´yhodou hald, kter´e jsme prob´ırali, je fakt, ˇze pracuj´ı jen s minimem nebo maximem, prob´ıran´e haldy nepracovaly s obˇema extr´emy najednou. C´ılem tohoto textu je se sezn´amit s datov´ymi strukturami, kter´e pracuje s v´ıce operacemi zaloˇzen´ymi na uspoˇr´ad´an´ı.
Nejprve si zadefinujeme naˇsi ´ulohu: M´ame univerzum U , kter´e se skl´ad´a z pˇrirozen´ych ˇc´ısel {0, 1, . . . , m − 1} pro nˇejak´e pˇrirozen´e ˇc´ıslo m. Chceme nal´ezt datovou strukturu reprezen- tuj´ıc´ı mnoˇziny S ⊆ U a umoˇzˇnuj´ıc´ı operace MEMBER, MIN, MAX, DELETE, IN- SERT, DELETEMIN, DELETEMAX, SUCCESSOR a PREDECESSOR.
Nejprve pop´ıˇseme pˇridan´e operace SUCCESSOR a PREDECESSOR. Pro reprezento- vanou mnoˇzinu S ⊆ U a prvek x ∈ U definujeme, ˇze SUCCESSOR(x) = min{t ∈ S | x ≤ t}, kdyˇz existuje t ∈ S takov´e, ˇze x ≤ t, nebo SUCCESSOR(x) = ∞, kdyˇz takov´e t ∈ S neexistuje. Zde ∞ form´alnˇe znamen´a nejvˇetˇs´ı prvek univerza (vˇsimnˇeme si, ˇze form´alnˇe plat´ı min∅ = ∞). D´ale PREDECESSOR(x) = max{t ∈ S | t ≤ x}, kdyˇz existuje t ∈ S takov´e, ˇze t ≤ x, v opaˇcn´em pˇr´ıpadˇe PREDECESSOR(x) = −∞, kde −∞ znamen´a nejmenˇs´ı prvek univerza (plat´ı max∅ = −∞).
Emde Boasova struktura.
Pop´ıˇseme si strukturu, kter´a ˇreˇs´ı tuto ´ulohu. Tato struktura na rozd´ıl napˇr. od vy- hled´avac´ıch strom˚u d´av´a omezen´ı na velikost univerza. Je zaloˇzena na vlastnostech celoˇc´ı- seln´ych operac´ı mod a ÷. Pˇripom´ın´ame, ˇze kdyˇz m, n, p a q jsou pˇrirozen´a ˇc´ısla takov´a, ˇze m = np + q a q < n, pak m ÷ n = p a q = m mod n. ˇC´ısla p a q jednoznaˇcnˇe reprezentuj´ı ˇc´ıslo m vzhledem k pevnˇe dan´emu n. To vede k pozorov´an´ı, ˇze kdyˇz m = nl, pak m˚uˇzeme mnoˇzinu S ⊆ U reprezentovat ve dvou univerzech, U velikosti l a U velikosti n pomoc´ı mnoˇzin S = {s ÷ n | s ∈ S} ⊆ U a S = {s mod n | s ∈ S} ⊆ U. To n´am umoˇzˇnuje ˇc´ınsk´a vˇeta o zbytc´ıch. Bohuˇzel pro dan´y prvek t∈ S bychom potˇrebovali spojit jeho reprezentaci jak v U tak v U. Nav´ıc tato reprezentace by poruˇsovala uspoˇr´ad´an´ı.
Kl´ıˇcem k ˇreˇsen´ı probl´emu je reprezentovat S⊆ U pomoc´ı mnoˇziny S ={s ÷ n | s ∈ S} ⊆ {0, 1, . . . , l−1} v univerzu U ={0, 1, . . . , l−1} a mnoˇzin Si ={s mod n | s ∈ S, s÷n = i}
pro i = 0, 1, . . . , l− 1 v univerzu U ={0, 1, . . . , n − 1}.
Tuto reprezentaci chceme pouˇz´ıt rekurzivnˇe. Proto je pˇrirozen´e poˇzadovat, aby n a l byla pˇribliˇznˇe stejnˇe velk´a (tj. bl´ızk´a √
m, kde m je velikost univerza). Pak bude rekurzivn´ıch krok˚u pˇribliˇznˇe log log m. Z tohoto d˚uvodu budeme pˇredpokl´adat, ˇze univerzum U je tvaru {0, 1, . . . , n − 1}, kde n = 2k pro nˇejak´e pˇrirozen´e ˇc´ıslo k. Datov´a struktura je definov´ana rekurzivnˇe a budeme j´ı ˇr´ıkat k-struktura (k je urˇceno velikost´ı univerza). Pˇredpokl´adejme, ˇze m´ame reprezentovat S ⊆ U. Nejdˇr´ıv poloˇzme k =k2 a k = k2.
Kdyˇz S ⊆ U je nepr´azdn´a, pak k-struktura reprezentuj´ıc´ı mnoˇzinu obsahuje (1) ˇc´ıslo |S|;
Typeset by AMS-TEX 1
(2) rostouc´ı dvousmˇern´y seznam tS vˇsech prvk˚u mnoˇziny S;
(3) kdyˇz |S| ≥ 2, pak pole PS[0, .., n− 1] ukazatel˚u, kde PS(i) =
prvek i v seznamu tS kdyˇz i∈ S,
N IL kdyˇz i /∈ S;
(4) kdyˇz |S| ≥ 2, pak k-strukturu T OPS reprezentuj´ıc´ı mnoˇzinu {s ÷ 2k | s ∈ S} ⊆ {0, 1, . . . 2k − 1}
a pole ukazatel˚u BOT T OMS[0, .., 2k−1] na k-struktury, kde struktura, na kterou ukazuje BOT T OMS(i), reprezentuje mnoˇzinu {s mod 2k | s ∈ S, s ÷ 2k = i}, kdyˇz je tato mnoˇzina nepr´azdn´a, a BOT T OMS(i) = N IL, kdyˇz neexistuje s∈ S takov´e, ˇze s÷ 2k = i.
To znamen´a, ˇze pr´azdnou mnoˇzinu reprezentuje pr´azdn´y ukazatel “N IL”. D´ale ukaza- tel BOT T OMS(i) budeme ztotoˇzˇnovat s k-strukturou, na kterou ukazuje. Pak S lze povaˇzovat za ukazatel na strukturu reprezentuj´ıc´ı mnoˇzinu S.
Algoritmy realizuj´ıc´ı operace MEMBER, MIN a MAX jsou jednoduch´e. Operace MEMBER vych´az´ı z toho, ˇze s /∈ S, pr´avˇe kdyˇz PS(s) = N IL, a operace MIN a MAX vyuˇz´ıvaj´ı toho, ˇze tS je rostouc´ı dvousmˇern´y seznam vˇsech prvk˚u v S.
MEMBER(x) if |S| > 1 then
if PS(x)= NIL then V´ystup: x ∈ S else
V´ystup: x /∈ S endif
endif
if |S| = 1 then
if x je prvek tS then V´ystup: x ∈ S else
V´ystup: x /∈ S endif
endif
if S = N IL then V´ystup: x /∈ S endif MIN
if |S| > 0 then
V´ystup: prvn´ı prvek v seznamu tS else
V´ystup: neexistuje endif
MAX if |S| > 0 then
V´ystup: posledn´ı prvek v seznamu tS else
V´ystup: neexistuje endif
DELETEMIN
if |S| = 1 then S := NIL, odstranit seznam tS endif if |S| = 2 then
|S| := 1, DELETE(prvn´ı prvek) v tS
odstranit PS, T OPS a BOT T OMS endif
if |S| > 2 then
x := prvn´ı prvek v seznamu tS, |S| := |S| − 1 x := x÷ 2k, x := x mod 2k
DELETEMIN v BOT T OMS(x) if BOT T OMS(x) = N IL then
DELETEMIN v T OPS, BOT T OMS(x) := N IL endif
DELETE(x) v seznamu tS, PS(x) := N IL endif
DELETEMAX
if |S| = 1 then S := NIL, odstranit seznam tS endif if |S| = 2 then
|S| := 1, DELETE(posledn´ı prvek) v tS
odstranit PS, T OPS a BOT T OMS endif
if |S| > 2 then
x := posledn´ı prvek v seznamu tS, |S| := |S| − 1 x := x÷ 2k, x := x mod 2k
DELETEMAX v BOT T OMS(x) if BOT T OMS(x) = N IL then
DELETEMAX v (T OPS), BOT T OMS(x) := N IL endif
DELETE(x) v seznamu tS (odzadu), PS(x) := N IL endif
Je lehce vidˇet, ˇze algoritmy pro operace MEMBER, MIN a MAX jsou korektn´ı a ˇze spotˇrebuj´ı konstantn´ı ˇcas.
Algoritmy, kter´e realizuj´ı operace DELETEMIN a DELETEMAX jsou sloˇzitˇejˇs´ı, proto- ˇze mus´ı tak´e upravit rekurzivn´ı struktury.
Vˇsimnˇeme si, ˇze DELETE v seznamu tS vyˇzaduje vˇzdy O(1) ˇcasu (protoˇze tS je dvousmˇer- n´y seznam a odstraˇnujeme prvn´ı nebo posledn´ı prvek). Pokud |S| ≤ 2, pak cel´a operace DELETEMIN a DELETEMAX bez rekurzivn´ıho vol´an´ı vyˇzaduje O(1) ˇcasu. Kdyˇz
algoritmus vol´a dvˇe rekurzivn´ı vol´an´ı sebe sama, pak jedno je pouˇzito na pˇr´ıpad, ˇze reprezentovan´a mnoˇzina m´a nejv´yˇse jeden prvek, a proto vyˇzaduje ˇcas O(1). Protoˇze kdyˇz nepoˇc´ıt´ame rekursivn´ı vol´an´ı sebe sama, tak algoritmus vyˇzaduje O(1) ˇcasu, tedy dost´av´ame, ˇze celkov´y ˇcas algoritmu je ´umˇern´y d´elce ˇretˇezce rekurzivn´ıch vol´an´ı sebe sama.
Korektnost algoritm˚u plyne z pozorov´an´ı, ˇze kdyˇz x = min(S) (x = max(S)), pak x je nejmenˇs´ı (nejvˇetˇs´ı) prvek v mnoˇzinˇe reprezentovan´e T OPS a x je nejmenˇs´ı (nejvˇetˇs´ı) prvek v mnoˇzinˇe reprezentovan´e v BOT T OMS(x).
Nyn´ı pop´ıˇseme algoritmy realizuj´ıc´ı operace INSERT a DELETE. Algoritmus DELETE zjist´ı, zda x ∈ S a kdyˇz ano, pak x odstran´ı z PS, tS a ze struktury BOT T OMS(x÷ 2k) odstran´ı prvek x mod 2k. Kdyˇz potom BOT T OMS(x÷ 2k) reprezentuje pr´azdnou mnoˇzinu, tj. BOT T OMS(x÷ 2k) = N IL, odstran´ı prvek x÷ 2k ze struktury T OPS. Algoritmus INSERT je inverzn´ı. Kdyˇz x /∈ S, pak x mod 2k pˇrid´a do BOT T OMS(x÷ 2k) a pokud tato struktura reprezentovala pr´azdnou mnoˇzinu, tak pˇrid´a prvek x÷ 2k
do struktury T OPS. Probl´em je, kam d´at x v seznamu tS. K tomu pouˇzijeme operaci SUCCESSOR(x) a pak uprav´ıme PS, tS a |S|.
INSERT(x) if |S| = 0 then
vytvoˇrme seznam tS ={x}, |S| = 1, stop endif
if |S| = 1 then
if x nen´ı prvek tS then
vloˇzme x do seznamu tS a vytvoˇrme pole ukazatel˚u PS for every u∈ tS do
PS(u) je ukazatel na prvek u v tS enddo
vytvoˇrme T OPS reprezentuj´ıc´ı{s ÷ 2k | s ∈ S}
vytvoˇrme pole ukazatel˚u BOT T OMS for every u∈ tS do
INSERT(u mod 2k) do BOT T OMS(u÷ 2k) enddo
|S| = 2 endif else
if PS(x) = N IL then
x := x÷ 2k, x := x mod 2k
if SUCCESSOR(x)= ∞ then y := SUCCESSOR(x)
endif
if BOT T OMS(x) =∅ then INSERT(x) do T OPS endif
INSERT(x) do BOT T OMS(x) if SUCCESSOR(x)= ∞ then
INSERT(x) do seznamu tS pˇred y else
INSERT(x) jako posledn´ı prvek seznamu tS endif
PS(x) := ukazuje na prvek x v seznamu tS, |S| := |S| + 1 endif
endif
DELETE(x)
if |S| = 1 a x je v seznamu tS then S := N IL, odstranit seznam tS endif
if |S| = 2 a x je v seznamu tS then
|S| := 1, DELETE(x) v seznamu tS
odstranit PS, T OPS a BOT T OMS endif
if |S| > 2 a PS(x)= NIL then
|S| := |S| − 1, x := x÷ 2k, x := x mod 2k
DELETE(x) v BOT T OMS(x) if BOT T OMS(x) = N IL then
DELETE(x) v T OPS endif
DELETE(x) v seznamu tS pomoc´ı PS(x), PS(x) := N IL endif
Vˇsimnˇeme si, ˇze operace DELETE na nejv´yˇse dvouprvkovou mnoˇzinu a operace INSERT na jednoprvkovou mnoˇzinu vyˇzaduj´ı ˇcas O(1) a nevolaj´ı samy sebe. Operace DELETE a INSERT na seznam tS vyˇzaduj´ı ˇcas O(1), protoˇze zn´ame pozici x v seznamu tS pomoc´ı ukazatele PS(x). Proto operace DELETE a INSERT, kdyˇz nepoˇc´ıt´ame rekursivn´ı vol´an´ı sebe sama, vyˇzaduj´ı O(1) ˇcasu. Kdyˇz DELETE pouˇzije dvˇe rekurzivn´ı vol´an´ı sebe sama, pak jedno je pouˇzito na pˇr´ıpad, ˇze reprezentovan´a mnoˇzina m´a nejv´yˇse dva prvky, kdyˇz INSERT pouˇzije dvˇe rekurzivn´ı vol´an´ı sebe sama, pak jedno je pouˇzito na pˇr´ıpad, ˇze reprezentovan´a mnoˇzina m´a nejv´yˇse jeden prvek, proto celkov´y ˇcas algoritm˚u je ´umˇern´y d´elce maxim´aln´ıho ˇretˇezc˚u rekurzivn´ıch vol´an´ı sebe sama.
Nyn´ı pop´ıˇseme algoritmus pro operaci SUCCESSOR(x). Algoritmus pop´ıˇseme jen pro pˇr´ıpad, ˇze x /∈ S, v opaˇcn´em pˇr´ıpadˇe je v´ysledek x a algoritmus je jasn´y. Vˇsimnˇeme si, ˇze kdyˇz existuje s ∈ S takov´e, ˇze s > x, pak buˇd existuje s ∈ S takov´e, ˇze s > x a s÷ 2k = x÷ 2k, a v tom pˇr´ıpadˇe
min{s ∈ S | s > x} = (x ÷ 2k)2k+ min{s ∈ S | s > x, s ÷ 2k = x÷ 2k}
nebo neexistuje s ∈ S takov´e, ˇze s > x a s ÷ 2k = x÷ 2k a v tom pˇr´ıpadˇe existuje s ∈ S ={s ÷ 2k | s ∈ S} takov´e, ˇze x < s. Pak pro y= min{s ÷ 2k | s ∈ S, s ÷ 2k >
x÷ 2k} plat´ı
min{s ∈ S | s > x} = y2k + min{s mod 2k | s ∈ S, s ÷ 2k = y}.
N´asleduj´ıc´ı algoritmus pr´avˇe realizuje tyto v´ypoˇcty. Algoritmus pro operaci PREDE- CESSOR(x) je zaloˇzen na symetrick´ych vztaz´ıch.
SUCCESSOR(x)
if S = N IL then SUCCESSOR(x) :=∞, stop endif if |S| = 1 then
nalezneme SUCCESSOR(x) pomoc´ı prohled´an´ı tS, stop endif
if PS(x)= NIL then
V´ystup: SUCCESSOR(x) := x else
x := x÷ 2k, x := x mod 2k
z := MAX v BOT T OMS(x)
if T OPS.P (x) = N IL nebo x > z then if SUCCESSOR(x)= ∞ v T OPS then
y := SUCCESSOR(x) v T OPS y := MIN v BOT T OMS(y)
V´ystup: SUCCESSOR(x) := y2k + y
else
V´ystup: SUCCESSOR(x) :=∞ endif
else
y := SUCCESSOR(x) v BOT T OMS(x) V´ystup: SUCCESSOR(x) := x2k + y
endif endif
PREDECESSOR(x)
if S = N IL then PREDECESSOR(x) :=−∞, stop endif if |S| = 1 then
nalezneme PREDECESSOR(x) pomoc´ı prohled´an´ı tS stop
endif
if PS(x)= NIL then
V´ystup: PREDECESSOR(x) := x else
x := x÷ 2k, x := x mod 2k
z := MIN v BOT T OMS(x)
if T OPS.P (x) = N IL nebo x < z then
if PREDECESSOR(x)= −∞ v T OPS then y := PREDECESSOR(x) v T OPS
y := MAX v BOT T OMS(y)
V´ystup: PREDECESSOR(x) := y2k+ y
else
V´ystup: PREDECESSOR(x) :=−∞
endif else
y := PREDECESSOR(x) v BOT T OMS(x) V´ystup: PREDECESSOR(x) := x2k + y
endif endif
Korektnost algoritm˚u plyne z pozn´amky pˇred algoritmem. D´ale si vˇsimnˇeme, ˇze kaˇzd´y bˇeh algoritmu SUCCESSOR nebo PREDECESSOR vol´a s´am sebe nejv´yˇse jednou a protoˇze operace MIN a MAX vyˇzaduj´ı ˇcas O(1), tak algoritmy SUCCESSOR a PREDECESSOR, kdyˇz nepoˇc´ıt´ame rekursivn´ı vol´an´ı sebe sama, vyˇzaduj´ı O(1) ˇcasu.
Proto celkov´y ˇcas algoritm˚u je ´umˇern´y d´elce ˇretˇezce rekurzivn´ıch vol´an´ı sebe sama.
D´ale si vˇsimnˇeme, ˇze kdyˇz nˇekter´y algoritmus pracuje v k-struktuˇre a vol´a s´am sebe, tak rekurzivnˇe volan´a verze algoritmu bude pracovat buˇd v k-struktuˇre nebo v k-struktuˇre.
Kdyˇz pouˇzije dvˇe vol´an´ı sebe sama, tak jedno vol´an´ı vyˇzadovalo tot´aln´ı ˇcas O(1). To znamen´a, ˇze d´elka ˇretˇezce rekuzivn´ıch vol´an´ı je nejv´yˇse log k. Protoˇze k = log n, tak algoritmy pro DELETEMIN, DELETEMAX, INSERT, DELETE, SUCCESSOR a PREDECESSOR bˇeˇz´ı v ˇcase O(log log n).
Jeˇstˇe odhadneme velikost reprezentace. Seznam tS a pole PS vyˇzaduj´ı velikost pamˇeti O(|U|). Z toho dostaneme, kdyˇz |U| = 2k a P (k) je velikost pamˇeti, kterou potˇrebujeme pro reprezentaci podmnoˇziny U , pak plat´ı
P (k) = O(2k) + (k
2 + 1)P (k 2).
Kdyˇz tuto rekurzi budeme postupnˇe dosazovat do vzoreˇcku, dostaneme
P (k) = O(2k) +
log k
i=1
O((k
2i + 1)22ik )
a odtud dost´av´ame, ˇze P (k) = O(2klog k), a protoˇze k = log|U|, tak dost´av´ame
Vˇeta. k-struktura reprezentuje podmnoˇziny univerza U , kde U ={0, 1, . . ., n−1} a n = 2k pro nˇejak´e pˇrirozen´e ˇc´ıslo k, a vyˇzaduje O(n log log n) pamˇeti. Operace MEMBER, MIN a MAX vyˇzaduj´ı ˇcas O(1) a operace INSERT, DELETE, DELETEMIN, DELETE- MAX, SUCCESSOR a PREDECESSOR vyˇzaduj´ı ˇcas O(log log n).
To znamen´a, ˇze tato implementace k-struktury se hod´ı jen pro reprezentaci mal´ych univerz (napˇr. kdyˇz U je nosn´a mnoˇzina grafu apod.).
Algoritmus pro operaci PREDECESSOR(x) lze realizovat jeˇstˇe jin´ym zp˚usobem. Nej- prve spoˇc´ıt´ame SUCCESSOR(x). Kdyˇz v´ysledek je x, pak i PREDECESSOR(x) =
x, jinak je to prvek v seznamu tS, kter´y pˇredch´az´ı SUCCESSOR(x) (prvn´ımu prvku pˇredch´az´ı−∞ a ∞ pˇredch´az´ı nejvˇetˇs´ı prvek v S).
Tato struktura se s v´yhodou pouˇz´ıv´a pro grafov´e algoritmy. Tam se setk´av´ame s r˚uzn´ymi modifikacemi t´eto ´ulohy. Jedna z podstatn´ych modifikac´ı je n´asleduj´ıc´ı. Univerzum jsou vˇsechna pˇrirozen´a ˇc´ısla, ale reprezentovan´a mnoˇzina S vˇzdy splˇnuje podm´ınku, ˇze max(S)− min(S) ≤ n pro fixovan´e n. Pak m´ısto S reprezentujeme mnoˇzinu {s mod n | s ∈ S} v univerzu {0, 1, . . ., n − 1} a zn´ame prvek s nejmenˇs´ım ohodnocen´ım, nechˇt je to prvek t a pamatujeme si jeho skuteˇcn´e ohodnocen´ı – oznaˇcme si ho min. Pak m˚uˇzeme pouˇz´ıt tuto strukturu pro ˇreˇsen´ı dan´e ´ulohy (kde univerzum m´a tvar U ={0, 1, . . . , n − 1}). Pole PS bude cyklus a my mus´ıme hl´ıdat nejmenˇs´ı prvek a jeho skuteˇcnou velikost. Skuteˇcn´e ohodnocen´ı prvku s je
min +(ohodnocen´ı(s)− ohodnocen´ı(t) mod n) kdyˇz s≥ t, min +n + ohodnoceni(s) kdyˇz s < t.
Protoˇze n´aroky na pamˇeˇt jsou d˚uleˇzitˇejˇs´ı neˇz n´aroky na ˇcas, hledaly se modifikace t´eto struktury, kter´e by mˇely menˇs´ı n´aroky na prostor i za cenu, ˇze se zhorˇs´ı ˇcasov´a sloˇzitost.
Prvn´ı pozorov´an´ı bylo, ˇze n´aroky t´eto datov´e struktury na prostor jsou zavinˇen´e polem PS a seznamem tS. Tyto struktury jsou tam proto, aby operace MEMBER, MIN a MAX vyˇzadovaly konstantn´ı ˇcas. Na druhou stranu je lehk´e naj´ıt algoritmy pro operace MEMBER, MIN a MAX, kter´e vyˇzaduj´ı ˇcas O(log log m), kde m je velikost univerza, a nepouˇz´ıvaj´ı pole PS a seznam tS. Jsou to jednoduch´e modifikace algoritmu pro operaci SUCCESSOR.
To vedlo k n´asleduj´ıc´ı modifikaci definice k-struktury. Mˇejme nepr´azdnou mnoˇzinu S ⊆ U.
Pak modifikovan´a k-struktura reprezentuj´ıc´ı S obsahuje (1) ˇc´ıslo |S|;
(2) kdyˇz |S| = 1, pak S je reprezentov´ana seznamem tS obsahuj´ıc´ı jej´ı jedin´y prvek;
(3) kdyˇz |S| ≥ 2, pak S je reprezentov´ana k-strukturou T OPS reprezentuj´ıc´ı mnoˇzinu {s ÷ 2k | s ∈ S} ⊆ {0, 1, . . . 2k − 1} a
polem ukazatel˚u BOT T OMS[0, .., 2k − 1] na k-struktury, kde BOT T OMS(i) ukazuje na k-struktura reprezentuj´ıc´ı mnoˇzinu {s mod 2k | s ∈ S, s ÷ 2k = i}, kdyˇz je tato mnoˇzina nepr´azdn´a a BOT T OMS(i) = N IL, kdyˇz je tato mnoˇzina pr´azdn´a.
Nyn´ı operace MEMBER, MIN a MAX vyuˇz´ıvaj´ı n´asleduj´ıc´ıch fakt˚u:
x ∈ S, pr´avˇe kdyˇz prvek x ÷ k je ve struktuˇre T OPS a prvek x mod k je ve struktuˇre BOT T OMS(x÷ k),
minim´aln´ı prvek v S je
2k(MIN(T OPS)) + MIN(BOT T OMS(MIN(T OPS))) a maxim´aln´ı prvek v S je
2k(MAX(T OPS)) + MAX(BOT T OMS(MAX(T OPS))).
MEMBER(x)
if |S| = 0 then V´ystup: x /∈ S, stop endif if |S| = 1 then
if x je v seznamu tS then V´ystup: x ∈ S, stop else
V´ystup: x /∈ S, stop endif
endif
x := x÷ 2k, x := x mod 2k
if x v T OPS then
if x v BOT T OMS(x) then V´ystup: x ∈ S
else
V´ystup: x /∈ S endif
else
V´ystup: x /∈ S endif
MIN
if |S| = 0 then neexistuje, stop endif if |S| = 1 then prvek v tS, stop endif
y:= MIN(T OPS), y := MIN(BOT T OMS(y)) y := y2k+ y
MAX
if |S| = 0 then neexistuje, stop endif if |S| = 1 then prvek v tS, stop endif
y:= MAX(T OPS), y := MAX(BOT T OMS(y)) y := y2k+ y
Algoritmy pro operace DELETEMIN a DELETEMAX se vlastnˇe zjednoduˇsˇs´ı.
DELETEMIN
if |S| = 1 then odstran´ıme tS a |S|, stop endif
y := MIN(T OPS), DELETEMIN v BOT T OMS(y) if BOT T OMS(y) = N IL then
DELETEMIN(T OPS) endif
|S| := |S| − 1 if |S| = 1 then
vytvoˇrme seznam tS obsahuj´ıc´ı prvek MIN(S) zruˇs T OPS a BOT T OMS
endif
DELETEMAX
if |S| = 1 then odstran´ıme tS a |S|, stop endif
y := MAX(T OPS), DELETEMAX v BOT T OMS(y) if BOT T OMS(y) = N IL then
DELETEMAX(T OPS) endif
|S| := |S| − 1 if |S| = 1 then
vytvoˇrme seznam tS obsahuj´ıc´ı prvek MIN(S) zruˇs T OPS a BOT T OMS
endif
Pˇri operaci INSERT se mˇen´ı instrukce pro |S| = 1, vytvoˇr´ı se jen seznam tS pro mnoˇzinu S a vynechaj´ı se pˇr´ıkazy pro PS a kdyˇz |S| > 1 tak se vynechaj´ı pˇr´ıkazy pro tS a PS. V pˇr´ıpadˇe, ˇze po ´uspˇeˇsn´e operaci INSERT je |S| = 2, tak se zruˇs´ı seznam tS. Algoritmus pro operaci DELETE, kdyˇz m´a odstranit prvek x∈ S, tak kdyˇz |S| > 1, odstran´ı prvek x mod 2k ze struktury BOT T OMS(x÷2k), a pak postupuje stejnˇe jako v algoritmech pro DELETEMIN a DELETEMAX. Algoritmy pro SUCCESSOR a PREDECESSOR se nemˇen´ı. Stejn´y argument jako pro klasickou k-strukturu zajist´ı, ˇze d´elka rekurzivn´ıch vol´an´ı sama sebe je log k = O(log log |U|).
Tedy zb´yv´a spoˇc´ıtat n´aroky na pamˇeˇt. Zde m´a rekurze jin´y tvar. Oznaˇcme σ(n) pros- tor potˇrebn´y pro vytvoˇren´ı modifikovan´e k-struktury, kdyˇz velikost univerza je n = 2k. Oznaˇcme k =k2 a k = k2. Pak plat´ı:
σ(n) = σ(2k) = σ(2k) + 2kσ(2k) + k
protoˇze z´apis velikosti |S| vyˇzaduje nejv´yˇse k bit˚u. Kdyˇz budeme pˇredpokl´adat, ˇze b a c jsou kladn´e konstanty takov´e, ˇze b + 1 < c a σ(|U|) ≤ b|U|−c pro |U| = 2. Pak dostaneme, ˇze (c− b)2k ≥ 2k > k a tedy bude platit
σ(n) =σ(2k) + 2kσ(2k) + k ≤ b2k − c + b2k2k − c2k + k = bn + (b− c)2k+ k− c ≤ bn − c.
Teˇd se jedn´a o splnˇen´ı inici´aln´ıch podm´ınek. Kdyˇz |U| = 2, pak reprezentace S ⊆ U vyˇzaduje nejv´yˇse 8 bit˚u a tedy staˇc´ı poloˇzit b = 9 a c = 10, pak 2b− c ≥ 8. Tedy m˚uˇzeme shrnout
Vˇeta. Modifikovan´a k-struktura reprezentuje podmnoˇziny univerza U = {0, 1, . . . , n − 1}, kde n = 2kpro nˇejak´e pˇrirozen´e ˇc´ıslo k, a vyˇzaduje O(n) pamˇeti. Pak operace MEMBER, MIN, MAX, INSERT, DELETE, DELETEMIN, DELETEMAX, SUCCESSOR a PREDECESSOR vyˇzaduj´ı ˇcas O(log log n).
D˚uleˇzit´a ot´azka je, zda lze tuto strukturu modifikovat tak, aby vyˇzadovala O(|S|) prostoru m´ısto O(|U|). Odpovˇeˇd je ˇze to lze, ale ˇcasov´a sloˇzitost bude horˇs´ı. Z´akladn´ı idea je, ˇze se
nahrad´ı struktury T OPS a BOT T OMS haˇsovac´ı tabulkou (kter´a odkazuje na nepr´azdn´e struktury BOT T OMS(i)), ale to se jeˇstˇe mus´ı kompresovat. V´ysledek pak je struktura, kter´a sice vyˇzaduje O(n) prostoru a operace MIN, MAX vyˇzaduj´ı O(log log|U|) ˇcasu, ale operace MEMBER, SUCCESSOR a PREDECESSOR maj´ı jen oˇcek´avanou sloˇzitost rovnou O(log log|U|) a operace INSERT a DELETE maj´ıjen oˇcek´avanou amortizovanou sloˇzitost O(log log|U|).
Tuto datovou strukturu navrhl van Emde Boas v roce 1977. Modifikovanou verzi navrhli van Emde Boas, Kaas a Zijlstra tak´e v roce 1977.
Dvoukoncov´e haldy
Hodnˇe ˇcasto pouˇz´ıvanou strukturou jsou haldy. V zimn´ım semestru jsme si uk´azali ‘jed- nokoncov´e’ haldy, mohli jsme pracovat buˇd s minimem nebo maximem. Uk´aˇzeme si teˇd
‘dvoukoncov´e’ haldy, kter´e jsou zobecnˇen´ım d-regul´arn´ıch hald (takto lze zobecnit i jin´y typ hald neˇz regul´arn´ı haldy). Tyto haldy budou podporovat n´asleduj´ıc´ı operace:
MIN, MAX, DELETEMIN, DELETEMAX, DECREASEKEY, INCREASE- KEY, INSERT, DELETE.
Pˇri operac´ıch DECREASEKEY, INCREASEKEY a DELETE zadavatel ´ulohy d´av´a adresu prvku, s n´ımˇz m´ame pracovat. Pˇri operaci INSERT pˇredpokl´ad´ame, ˇze zadavatel zajistil, aby vkl´adan´y prvek v haldˇe nebyl reprezentov´an.
D´ale budeme uvaˇzovat jen haldy, kter´e jsou buˇd strom nebo soubor strom˚u. ˇRekneme, ˇze halda je min-halda (resp. max-halda) kdyˇz vrchol reprezentuje vˇzdy prvek vˇetˇs´ı (resp.
menˇs´ı) nebo roven neˇz je prvek reprezentovan´y otcem. Budeme pˇredpokl´adat, ˇze min- halda podporuje operace spojen´e s minimem a nikoliv operace spojen´e s maximem, kdeˇzto max-halda podporuje operace spojen´e s maximem a nikoliv s minimem. Naˇs´ım c´ılem bude zkonstruovat haldu podporuj´ıc´ı operace jak s minimem tak s maximem. D´ale pˇredpokl´ad´a- me, ˇze haldy podporuj´ı operace INSERT, INCREASEKEY, DECREASEKEY, a DELETE.
Dvoukoncov´e regul´arn´ı haldy.
M´ame univerzum U , podmnoˇzinu S ⊆ U a hodnot´ıc´ı funkci f z S do line´arnˇe uspoˇr´adan´e mnoˇziny. Pop´ıˇseme min-max-haldu reprezentuj´ıc´ı S a funkci f . Bude tvoˇrena d-regul´arn´ı min-haldou a stejnˇe velkou d-regul´arn´ı max-haldou a promˇennou f ree.
Kdyˇz|S| je sud´e, pak free je pr´azdn´e, kdyˇz |S| je lich´e, pak free obsahuje prvek z mnoˇziny S takov´y, ˇze min S = min S \ {free} a max S = max S \ {free}. D´ale m´ame disjunktn´ı mnoˇziny S1 a S2 takov´e, ˇze S \ {free} = S1 ∪ S2. Tedy |S1| = |S2| = |S|2 , Nechˇt T1
je d-regul´arn´ı min-halda reprezentuj´ıc´ı S1 a T2 je d-regul´arn´ı max-halda reprezentuj´ıc´ı S2 takov´e, ˇze:
(•) pro kaˇzd´e i je prvek s ∈ S1 reprezentovan´y i-t´ym listem v haldˇe T1 menˇs´ı neˇz prvek s ∈ S2 reprezentovan´y i-t´ym listem v haldˇe T2.
Pˇredpokl´ad´ame, ˇze listy jsou oˇc´ıslov´any v lexikografick´em uspoˇr´adan´ı bin´arn´ı haldy.
Nyn´ı pop´ıˇseme operace v t´eto haldˇe. Budeme pouˇz´ıvat operace definovan´e v zimn´ım semestru pro bin´arn´ı haldu, jen budeme rozliˇsovat, jestli jsou pro min-haldu (to je halda
T1) nebo max-haldu (to je T2). Rozd´ıl je v pomocn´e operaci D-DOWN, kter´a m˚uˇze proj´ıt obˇema haldami. V algoritmu pro operaci DELETE pouˇzijeme tuto proceduru D-DOWN m´ısto procedury DOWN pro jednokoncov´e haldy.
Algoritmy UP a DOWN pro max-haldu budeme naz´yvat M-UP a M-DOWN. Proce- dura M-UP vymˇeˇnuje prvky reprezentovan´e vrcholem a jeho otcem, kdyˇz otec reprezen- tuje menˇs´ı prvek a proceduru M-DOWN vymˇeˇnuje prvek reprezentovan´y vrcholem s nejvˇetˇs´ım prvkem reprezentovan´y jeho syny, pokud tento prvek je menˇs´ı. Procedura D- DOWN(x) se liˇs´ı podle toho, zda x je v min-haldˇe nebo max-haldˇe. Kdyˇz x je v min-haldˇe, tak provede DOWN(x) a kdyˇz skonˇc´ı v i-t´em listˇe, tak porovn´a prvky reprezentovan´e v i-t´em listˇe min-haldy a v i-t´em listˇe max-haldy. Pokud v min-haldˇe i-t´y list reprezentuje vˇetˇs´ı prvek, tak je vymˇen´ı a provede na i-t´y list max-haldy proceduru M-UP. Kdyˇz x je v max-haldˇe tak provede M-DOWN(x). Kdyˇz skonˇc´ı v i-t´em listˇe, tak porovn´a prvky reprezentovan´e v i-t´em listˇe max-haldy a v i-t´em listˇe min-haldy. Pokud v min-haldˇe i-t´y list reprezentuje vˇetˇs´ı prvek, tak je vymˇen´ı a provede na i-t´y list min-haldy proceduru UP.
Dalˇs´ı operace jsou stejn´e jako v d-regul´arn´ıch hald´ach.
D-DOWN(x) if x je prvek v T1 then
DOWN(x, T1)
if x je reprezentov´an i-t´ym listem T1 then y je reprezentov´an i-t´ym listem T2 if f (x) > f (y) then
i-t´y list T1 reprezentuje y, i-t´y list T2 reprezentuje x M-UP(x, T2)
endif endif else
M-DOWN(x, T2)
if x je reprezentov´an i-t´ym listem T2 then y je reprezentov´an i-t´ym listem T1 if f (x) < f (y) then
i-t´y list T1 reprezentuje x, i-t´y list T2 reprezentuje y UP(x, T1)
endif endif endif
DELETEMIN if f ree= ∅ then
key(koˇren T1) := f ree, D-DOWN(koˇren T1), f ree :=∅ else
DELETEMIN(T1)
f ree := prvek reprezentovan´y posledn´ım listem T2 DELETE(posledn´ı list T2)
endif
DELETEMAX if f ree= ∅ then
key(koˇren T2) := f ree, D-DOWN(koˇren T2), f ree :=∅ else
DELETEMAX(T2)
f ree := prvek reprezentovan´y posledn´ım listem T1 DELETE(posledn´ı list T1)
endif MIN
V´ystup: prvek reprezentovan´y koˇrenem T1 MAX
V´ystup: prvek reprezentovan´y koˇrenem T2 INSERT(x)
y := key(koˇren T1), z := key(koˇren T2) if x < y then
vymˇen´ıme x a y endif
if z < x then vymˇen´ıme x a z endif
if f ree =∅ then f ree := x else
a := min{x, free}, b := max{x, free}
INSERT(a, T1), INSERT(b, T2) f ree :=∅
endif
DECREASEKEY(x, a) f (x) := a
if x∈ T1 then UP(x, T1) else
D-DOWN(x, T2) endif
INCREASEKEY(x, a) f (x) := a
if x∈ T2 then UP(x, T2) else
D-DOWN(x, T1) endif
DELETE(x)
x je reprezentov´an v Ti, j := 3− i DELETE(x, Ti)
if f ree= ∅ then
y := prvek reprezentovan´y posledn´ım listem Tj DELETE(posledn´ı listTj)
if i = 1 a f ree≤ y nebo i = 2 a y ≤ free bf then INSERT(f ree, Ti)
else
INSERT(y, Ti), Insert(f ree, Tj) endif
f ree :=∅ else
f ree := prvek reprezentovan´y posledn´ım listem Tj DELETE(posledn´ı list Tj)
endif
Je lehk´e vidˇet, ˇze tuto strukturu lze reprezentovat pomoc´ı dvou stejnˇe velk´ych pol´ı repre- zentuj´ıc´ıch d-regularn´ı haldy T1 a T2a promˇennou free. Algoritmy vyuˇzij´ı znalosti um´ıstˇen´ı syn˚u a otce v tomto poli.
Shrneme z´ıskan´e v´ysledky.
Vˇeta. V navrhnut´e min-max haldˇe operace MIN a MAX vyˇzaduj´ı ˇcas O(1), operace DELETEMIN, DELETEMAX, INSERT, DECREASEKEY, INCREASEKEY, DELETE vyˇzaduj´ı ˇcas O(log n), kde n je velikost reprezentovan´e mnoˇziny. Tuto haldu lze reprezentovat pomoc´ı dvou pol´ı.
Lze uk´azat, ˇze oˇcek´avan´y ˇcas operace INSERT je O(1) (stejnˇe jako v regul´arn´ıch hald´ach).
Ponˇekud komplikovanˇejˇs´ı je algoritmus na konstrukci t´eto haldy v line´arn´ım ˇcase.
Algoritmus pro vytvoˇren´ı haldy pop´ıˇseme neform´alnˇe. Pˇredpokl´adejme, ˇze vstup je pos- loupnost prvk˚u a1, a2, . . . , an spolu s hodnot´ıc´ı funkc´ı f . Kdyˇz n je lich´e, pak nalezneme prostˇredn´ı prvek mezi prvky a1, a2 a a3. Tento prostˇredn´ı prvek vymˇen´ıme s prvkem an a vloˇz´ıme ho do promˇenn´e f ree a prvek an odstran´ıme. Tedy m˚uˇzeme pˇredpokl´adat, ˇze n = 2m je sud´e. Nyn´ı prvky a1, a2, . . . , am vloˇz´ıme do pole M in a prvky am+1, am+2, . . . , an vloˇz´ıme do pole M ax. Pak poloˇzime k := m−2d + 1 a pro i = k, k + 1, . . . , m porovn´ame prvky M in(i) a M ax(i) a pokud f (M ax(i)) < f (M in(i)) tak je vymˇen´ıme. D´al budeme pro i = k, k−1, . . . , 1 v klesaj´ıc´ım poˇrad´ı prov´adˇet modifikaci operac´ı D-DOWN(Min(i)) a D-DOWN(M ax(i)). Tato operace skonˇc´ı, kdyˇz se aplikuje ve struktuˇre T1 a pˇri prov´adˇen´ı operace M-UP se dostala do prvku um´ıstˇen´eho v poli M ax(l) pro l < i nebo kdyˇz se aplikuje ve struktuˇre T2 a pˇri prov´adˇen´ı operace UP se dostala do prvku um´ıstˇen´eho v poli M in(l) pro l < i.
Tento postup zajist´ı, ˇze kdyˇz se prov´ad´ı tyto operace pro i, pak pro kaˇzd´e j > i plat´ı, ˇze f (M in(j)) je menˇs´ı neˇz hodnota f od syn˚u vrcholu M in(j) v haldˇe T1 a f (M ax(j)) je vˇetˇs´ı neˇz hodnota f od syn˚u vrcholu M ax(j) v haldˇe T2. Proto po skonˇcen´ı pole M in reprezentuje min-haldu a pole M ax reprezentuje max-haldu, kter´e reprezentuj´ı disjunktn´ı podmnoˇziny mnoˇziny S o velikosti n2 a pˇr´ıpadnˇe zb´vaj´ıc´ı prvek je v promˇenn´e free.
Nav´ıc, kdyˇz vrchol i je ve v´yˇsce h, pak tato operace vyˇzaduje ˇcas O(h). Podle stejn´eho v´ypoˇctu jako pro d-regul´arn´ı haldy dostaneme, ˇze tato operace vyˇzaduje ˇcas O(n).
Tuto strukturu (pro bin´arn´ı haldy) navrhl Williams v roce 1964, kdyˇz definoval bin´arn´ı haldy. Podrobnˇe jsou spoˇc´ıtan´e Knuthem v jeho monografii Art of Programming III.
Symetrick´a min-max halda.
Nyn´ı pop´ıˇseme tzv. symetrickou min-max haldu. Bin´arn´ı halda T ohodnocen´a prvky z mnoˇziny S je symetrickou min-max haldou reprezentuj´ıc´ı mnoˇzinu S, kdyˇz plat´ı:
(1) r˚uzn´e prvky mnoˇziny S ohodnocuj´ı r˚uzn´e vrcholy haldy a koˇren haldy nen´ı ohod- nocen ˇz´adn´ym prvkem z S;
(2) pro kaˇzd´y vnitˇrn´ı vrchol v, kdyˇz s je ohodnocen´ı lev´eho syna vrcholu v a t je ohodnocen´ı prav´eho syna vrcholu v, pak plat´ı s ≤ u ≤ t pro kaˇzd´y prvek u z S, kter´y ohodnocuje nˇekter´y vrchol w v podstromu urˇcen´em vrcholem v a v= w.
Tedy pro kaˇzd´y vrchol v stromu T plat´ı: kdyˇz Sv je mnoˇzina prvk˚u z S reprezentovan´ych nˇejak´ym vrcholem w v podstromu T urˇcen´em vrcholem v, v = w, pak lev´y syn vrcholu v reprezentuje minimum mnoˇziny Sv a prav´y syn v reprezentuje maximum mnoˇziny Sv. Proto minimum mnoˇziny S je reprezentov´ano lev´ym synem koˇrene a maximum je reprezen- tov´ano prav´ym synem koˇrene.
Operace jsou prakticky stejn´e jako v bin´arn´ı haldˇe, jen operace UP(x) a DOWN(x) jsou sloˇzitˇejˇs´ı. Nejprve pop´ıˇseme operaci UP(x). Kdyˇz otec vrcholu reprezentuj´ıc´ıho x je koˇren, operace konˇc´ı. V opaˇcn´em pˇr´ıpadˇe, kdyˇz x je menˇs´ı neˇz prvek reprezentovan´y lev´ym synem dˇeda vrcholu reprezentuj´ıc´ıho x, pak si x s t´ımto prvkem vymˇen´ı m´ısto. Kdyˇz x je vˇetˇs´ı neˇz prvek reprezentovan´y prav´ym synem dˇeda vrcholu reprezentuj´ıc´ıho x, pak si x s t´ımto prvkem vymˇen´ı m´ısto. Kdyˇz si x nevymˇenilo m´ısto s ˇz´adn´ym prvkem, pak operace konˇc´ı, v opaˇcn´em pˇr´ıpadˇe se akce zopakuje s x.
Nyn´ı pop´ıˇsme operaci DOWN(x). Pˇredpokl´adejme, ˇze x je reprezentov´an vrcholem v.
Kdyˇz v je list, operace konˇc´ı. Kdyˇz v nen´ı list, pak setˇr´ıd´ı mnoˇzinu obsahuj´ıc´ı x a prvky reprezentovan´e syny vrcholu v. Nyn´ı uprav´ıme reprezentaci prvk˚u v t´eto mnoˇzinˇe tak, aby platilo:
(•) kdyˇz v je lev´ym synem sv´eho otce, pak reprezentuje nejmenˇs´ı prvek z t´eto mnoˇziny, lev´y syn v reprezentuje prostˇredn´ı prvek mnoˇziny a prav´y syn v reprezentuje nejvˇetˇs´ı prvek mnoˇziny;
(•) kdyˇz v je prav´ym synem sv´eho otce, pak lev´y syn v reprezentuje nejmenˇs´ı prvek mnoˇziny, prav´y syn v reprezentuje prostˇredn´ı prvek mnoˇziny a v reprezentuje nejvˇetˇs´ı prvek mnoˇziny.
Kdyˇz vrchol v nereprezentuje x, pak provedeme stejnou akci na vrchol reprezentuj´ıc´ı prvek x. Operace konˇc´ı, kdyˇz v reprezentuje x.
Form´aln´ı popis tˇechto pomocn´ych procedur:
UP(x)
v := vrchol reprezentuj´ıc´ı x
if otec(v) je koˇren then stop endif y := key(levy(ded(v)))
if x < y then
key(levy(ded(v))) := x, key(v) := y, UP(x) endif
z := key(pravy(ded(v))) if z < x then
key(pravy(ded(v))) := x, key(v) := z, UP(x) endif
DOWN(x)
v := vrchol reprezentuj´ıc´ı x if v je list then stop endif
s := key(levy(v)), t := key(pravy(v)) if v je lev´y syn sv´eho otce then
key(v) := min{s, x, t}, key(pravy(v)) := max{s, x, t}
key(levy(v)) := median z mnoˇziny {s, x, t}
if key(v)= x then DOWN(x) endif else
key(v) := max{s, x, t}, key(levy(v)) := min{s, x, t}
key(pravy(v)) := median z mnoˇziny {s, x, t}
if key(v)= x then DOWN(x) endif endif
Algoritmy pro ostatn´ı operace jsou stejn´e jako pro bin´arn´ı haldy.
Reflex-halda.
Na z´avˇer si uk´aˇzeme metodu, jak zobecnit jednokoncovou haldu, kter´a pˇripouˇst´ı jen ope- race MIN, DELETEMIN, INSERT, MERGE, DECREASEKEY a INCREASE- KEY a nikoliv MAX a DELETEMAX, na dvoukoncovou haldu (tj. haldu, jeˇz m´a tak´e operace MAX a DELETEMAX). Pˇredpokl´adejme, ˇze m´ame ‘stromovou’ min- haldu Qmin (tj. prov´ad´ı operace MIN, DELETEMIN, INSERT, MERGE, DEC- REASEKEY a INCREASEKEY) a halda pouˇz´ıv´a jen ukazatele na syny a otce. Nechˇt Qmax je du´aln´ı halda, tj. reprezentuje operace MAX, DELETEMAX, INSERT, MER- GE, DECREASEKEY a INCREASEKEY. Budeme pˇredpokl´adat kv˚uli jednoduˇs´ımu popisu, ˇze pouˇz´ıv´ame jen bin´arn´ı haldu, tj. ukazatel´e jsou levy a pravy.
Reflex-halda je zobecnˇen´ım min-max-haldy definovan´e Williamsem. Reflex-halda reprezen- tuj´ıc´ı mnoˇzinu S, kterou tady chceme uk´azat, pouˇz´ıv´a jednu Qmin o velikosti |S|2 jednu Qmax o velikosti |S|2 a promˇennou free. Kdyˇz |S| je sud´e, pak free je pr´azdn´e, kdyˇz
|S| je lich´e pak free obsahuje prvek z S takov´y, ˇze min S = min S \ {free} a max S =
max S \ {free}. D´ale Qmin a Qmax reprezentuj´ı disjunktn´ı mnoˇziny S1 a S2 takov´e, ˇze
|S1| = |S2| = |S|2 a S1∪ S2 = S\ {free}. Nav´ıc pro kaˇzd´y vrchol v haldy Qmin je d´an ukazatel vb na vrchol haldy Qmax a pro kaˇzd´y vrchol u haldy Qmax je d´an ukazatel ub na vrchol haldy Qmin takov´y, ˇze pro kaˇzd´y vrchol v haldy Qmin plat´ı (vb)b = v a prvek reprezentovan´y vrcholem v je menˇs´ı neˇz prvek reprezentovan´y vrcholem vb.
Operace INSERT(x) je velmi podobn´a operaci INSERT v haldˇe navrˇzen´e Williamsem.
Nejprve se zkontroluje, zda x nen´ı menˇs´ı neˇz nejmenˇs´ı prvek nebo vˇetˇs´ı neˇz nejvˇetˇs´ı. Pokud toto nastane, tak se x s pˇr´ısluˇsn´ym prvkem vymˇen´ı. Pak kdyˇz f ree je pr´azdn´e, tak se x vloˇz´ı do f ree, kdyˇz f ree nen´ı pr´azdn´e, tak se v min-haldˇe i max-haldˇe vytvoˇr´ı nov´y vrchol, tyto prvky budou sp´arov´any ukazateli a vloˇz´ı se na nˇe hodnoty x a f ree (t´ım se f ree vypr´azdn´ı) a operac´ı UP se prvky pˇresunou na spr´avn´e m´ısto. Operace DELETE(x), kdyˇz f ree je pr´azdn´e, tak pˇresune kl´ıˇc sp´arovan´eho vrcholu do f ree a uprav´ı tvar haldy, kdyˇz f ree je nepr´azdn´e, tak hodnota f ree nahrad´ı odstranˇen´y prvek a zase se operacemi DOWN a UP zajist´ı spr´avn´y tvar haldy. Pˇri operac´ıch UP a DOWN se ukazatel´e mezi prvky pohybuj´ı souˇcasnˇe s prvky (nikoliv s vrcholy). To zajiˇsˇtuje splnˇen´ı podm´ınky, ˇze vrchol min-haldy v reprezentuje prvek menˇs´ı neˇz vrchol vb. Ostatn´ı operace se provedou pomoc´ı tˇechto operac´ı.
V´yznam t´eto metody je, ˇze kdyˇz m´ame haldu, kter´a provede INSERT v konstantn´ım ˇcase, tak i tato halda bude vyˇzadovat konstantn´ı ˇcas a ˇze analogicky lze prov´est operaci MERGE. To znamen´a
Vˇeta. Existuje-li min-halda, na kterou lze aplikovat tuto metodu a splˇnuje poˇzadavky, pak vytvoˇren´a reflex-halda provede v nejhorˇs´ım pˇr´ıpadˇe operace MIN, MAX, INSERT a MERGE v ˇcase O(1) a operace DELETE, DELETEMIN, DELETEMAX, DEC- REASEKEY, INCREASEKEY v ˇcase O(log n), kde n je velikost reprezentovan´e mno- ˇziny.
Metoda konstrukce reflex-haldy lze zobecnit i na haldy tvoˇren´e souborem strom˚u. V tomto zobecnˇen´ı nen´ı nutn´e, aby kaˇzd´y vrchol min-haldy byl spojen s vrcholem max-haldy. Staˇc´ı jen, aby kaˇzd´y list min-haldy byl spojen s nˇekter´ym vrcholem max-haldy a kaˇzd´y list max-haldy byl spojen s nˇekter´ym vrcholem min-haldy, a aby platilo, ˇze kdyˇz vrchol v v min-haldˇe je spojen s vrcholem w v max-haldˇe, tak f (key(v))≤ f(key(w)). Zde se m˚uˇze m´ısto procedur UP a DOWN m˚uˇze pouˇz´ıt metoda odtrh´av´an´ı podstrom˚u.
Symetrickou min-max haldu navrhli Arvind a Pandu Rangan v roce 1999, reflected min- max haldu navrhli Makris, Tsakalidis a Tsichlas v roce 2003.
Modifikace Fibonacciho hald
Pˇri standardn´ı implementaci Fibonacciho haldy m´a kaˇzd´y vrchol, alespoˇn ˇctyˇri ukazatele.
Tak´e se uk´azalo, ˇze operace DECREASEKEY m´a sice amortizovanou sloˇzitost O(1), ale v nejhorˇs´ım pˇr´ıpadˇe m´a sloˇzitost Ω(n). Proto multiplikativn´ı konstanta schovan´a v notaci O je velk´a, takˇze se nedoporuˇcuj´ı pro praktick´e pouˇzit´ı. To vedlo ke snaze nal´ezt haldy,
kter´e jsou rychlejˇs´ı, vyˇzaduj´ı m´enˇe pamˇeti (pˇresnˇeji, pouˇz´ıvaj´ı m´enˇe ukazatel˚u) a asymp- toticky maj´ı stejn´e chov´an´ı jako Fibonacciho haldy. Tady uk´aˇzu modifikace Fibonacciho hald splˇnuj´ıc´ı tyto poˇzadavky.
Tenk´a halda.
Tenk´a halda bude soubor koˇrenov´ych strom˚u, kde kaˇzd´y vrchol v m´a definovan´y rank(v) (rank(v) zde nen´ı poˇcet syn˚u vrcholu v, i kdyˇz souvis´ı s t´ımto poˇctem). Je d´ana bijekce z vrchol˚u tˇechto strom˚u na reprezentovanou mnoˇzinu takov´a, ˇze pro kaˇzd´y vrchol v r˚uzn´y od koˇrene plat´ı f (v) ≥ f(otec(v)). Tedy koˇren stromu m´a nejmenˇs´ı ohodnocen´ı mezi prvky reprezentovan´e t´ımto stromem. Stromy jsou v jednosmˇern´em seznamu a n´azev haldy m´a ukazatel na prvn´ı a posledn´ı strom v tomto seznamu (aby ˇsla dobˇre prov´adˇet konkatenace seznam˚u) a ukazatel na koˇren stromu, kter´y m´a nejmenˇs´ı ohodnocen´ı (aby operace MIN vyˇzadovala konstantn´ı ˇcas). Tedy se jedn´a o min-haldu.
Stromy budou reprezentov´any pomoc´ı seznam˚u syn˚u jednotliv´ych vrchol˚u. Struktura vr- chol˚u strom˚u tenk´e haldy:
(•) ukazatel levy(v) m´a hodnotu NIL, kdyˇz v je koˇren, ukazuje na otce v, kdyˇz v je prvn´ı prvek v seznamu syn˚u otce v, na pˇredch˚udce v v seznamu syn˚u otce v, kdyˇz v nen´ı ani koˇren ani nen´ı prvn´ı prvek v seznamu syn˚u otce v;
(•) ukazatel pravy(v) ukazuje na koˇren n´asleduj´ıc´ıho stromu v seznamu strom˚u, kdyˇz v je koˇren, ale nen´ı posledn´ı prvek v seznamu strom˚u, na prvek n´asleduj´ıc´ı za vrcholem v v seznamu syn˚u otce vrcholu v, kdyˇz v nen´ı posledn´ı prvek v seznamu syn˚u otce v, a m´a hodnotu N IL, kdyˇz v je posledn´ı koˇren v seznamu strom˚u nebo posledn´ı prvek v seznamu syn˚u otce v;
(•) ukazatel prvni(v) ukazuje na prvn´ı prvek v seznamu syn˚u vrcholu v, pokud v nen´ı list a m´a hodnotu N IL, kdyˇz v je list;
(•) promˇennou key(v) d´avaj´ıc´ı prvek reprezentovan´y vrcholem v;
(•) promˇennou rank(v) obsahuj´ıc´ı hodnotu ranku vrcholu v.
Vrcholy strom˚u budou splˇnovat n´asleduj´ıc´ı podm´ınky:
(h1) kdyˇz vrchol v m´a k syn˚u, pak synov´e budou m´ıt hodnotu ranku k− 1, k − 2, . . . , 0 a syn vrcholu v s rankem i bude (k− i)-t´ym prvkem seznamu syn˚u vrcholu v (tj.
rank(prvni(v)) = k− 1, a kdyˇz w je syn vrcholu v, pak
rank(levy(w)) = rank(w) + 1 kdyˇz w nen´ı prvn´ı prvek v seznamu syn˚u vrcholu v, rank(w) = rank(pravy(w)) +1, kdyˇz w nen´ı posledn´ı prvek v seznamu syn˚u vrcholu v,
rank(w) = 0 kdyˇz w je posledn´ı prvek v seznamu syn˚u v);
(h2) kdyˇz vrchol v m´a k syn˚u, pak bude m´ıt rank k nebo k + 1, v prvn´ım pˇr´ıpadˇe to bude norm´aln´ı vrchol v druh´em pˇr´ıpadˇe to bude tenk´y vrchol;
(h3) koˇren kaˇzd´eho stromu bude norm´aln´ı vrchol.
Tedy kaˇzd´y vrchol stromu v m´a nejv´yˇse tˇri ukazatel´e. Tato struktura umoˇzˇnuje v kons- tantn´ım ˇcase testovat, zda vrchol je koˇren stromu (tj. zda levy(v) = N IL), zda je prvn´ım synem sv´eho otce (tj. zda prvni(levy(v)) = v) a zda je tenk´y (tj. zda rank(v) = 1 a prvni(v) = N IL nebo rank(v) = rank(prvni(v)) + 2).
Rank stromu je rank jeho koˇrene. Pro dva stromy T1 a T2 o stejn´em ranku je definov´ana operace LINK(T1, T2), kter´a je spoj´ı do jednoho stromu. Vezme strom, jehoˇz koˇren m´a vˇetˇs´ı ohodnocen´ı a jeho koˇren udˇel´a prvn´ım synem druh´eho stromu a rank koˇrene druh´eho stromu zvˇetˇs´ı o 1 (viz analogick´e operace u binomi´aln´ıch hald a Fibonacciho hald). Tato operace vyˇzaduje O(1) ˇcasu stejnˇe jako pro binomi´aln´ı nebo Fibonacciho haldy. Vˇsimnˇeme si, ˇze kdyˇz strom m´a rank i a vˇsechny jeho vrcholy jsou norm´aln´ı, pak je izomorfn´ı s binomi´aln´ım stromem Hi. Proto tenk´y vrchol, m´a podobn´y semantick´y v´yznam jako oznaˇcen´y vrchol ve Fibonacciho haldˇe.
Lemma. Kdyˇz v je vrchol stromu v tenk´em haldˇe a m´a i syn˚u, pak jeho podstrom m´a alespoˇn Fi+2 vrchol˚u, kde Fi je i-t´e Fibonacciho ˇc´ıslo.
D˚ukaz. Tvrzen´ı dok´aˇzeme indukc´ı podle poˇctu syn˚u. Kdyˇz vrchol nem´a syna, pak jeho podstrom m´a jeden vrchol a F2 = 1. Kdyˇz m´a jednoho syna, pak jeho podstrom m´a alespoˇn dva vrcholy a F3 = 2. D´ale si staˇc´ı uvˇedomit, kdyˇz vrchol m´a k syn˚u, pak jeho synov´e maj´ı rank od k− 1 do 0 a vrchol s rankem i m´a nejv´yˇse i a alespoˇn i − 1 syn˚u.
Tedy z indukce dost´av´ame, ˇze podstrom m´a alespoˇn 1 +k−1
i=0 Fi+2 = k+1
i=1 Fi = Fk+2 vrchol˚u.
Nyn´ı pop´ıˇseme operace v tenk´ych hald´ach. Mˇejme dvˇe tenk´e haldy H1a H2, kter´e reprezen- tuj´ı disjunktn´ı mnoˇziny. Operace MERGE(H1, H2) provede konkatenci seznam˚u strom˚u a aktualizuje ukazatele novˇe vytvoˇren´e haldy. Operace INSERT(x) vytvoˇr´ı novou haldu reprezentuj´ıc´ı {x} a pak provede na obˇe haldy operaci MERGE. Operace MIN z´ısk´a v´ysledek pouˇzit´ım ukazatele na koˇren stromu reprezentuj´ıc´ıho prvek s nejmenˇs´ım ohod- nocen´ım. Operace DELETEMIN stejnˇe jako operace MIN nalezne prvek, kter´y m´a odstranit a po jeho odstranˇen´ı provede konzolidaci seznamu strom˚u a seznamu podstrom˚u urˇcen´ych syny odstranˇen´eho vrcholu.
Pop´ıˇseme konzolidaci. Z Lemmatu plyne, ˇze rank nem˚uˇze b´yt vˇetˇs´ı neˇz 1 +1.44 log n. Tedy vytvoˇrme pole O o velikosti 1 +1.44 log n. Proch´azejme pole strom˚u a strom s rankem k se pokusme vloˇzit na m´ısto O(k). Pak proch´az´ıme pole syn˚u odstranˇen´eho vrcholu x.
Kdyˇz syn je tenk´y tak zmenˇs´ıme jeho rank o 1 a pak se ho pokus´ıme vloˇzit na m´ısto O(k), kde k je jeho aktualizovan´y rank. Pokus o vloˇzen´ı vrcholu v s rankem k je n´asleduj´ıc´ı akce:
Kdyˇz je m´ısto O(k) voln´e, pak tam v vloˇz´ıme, v opaˇcn´em pˇr´ıpadˇe provedeme operaci LINK na podstrom urˇcen´y vrcholem v a na podstrom urˇcen´ym vrcholem v O(k), novˇe z´ıskan´y strom zkus´ıme vloˇzit na m´ısto O(k + 1) a m´ısto O(k) se upr´azdn´ı. Toto opakujeme dokud se n´am nepodaˇr´ı strom vloˇzit do pole O.
Nyn´ı pop´ıˇseme algoritmy pro operace DECREASEKEY a INCREASEKEY, kter´e se v´yraznˇe liˇs´ı od algoritm˚u pro Fibonacciho haldy. Nejprve pop´ıˇseme z´akladn´ı tˇelo obou algoritm˚u. Uvaˇzujme algoritmus pro DECREASEKEY(v, d), tj. chceme zmenˇsit ohod- nocen´ı prvku reprezentovan´eho vrcholem v o hodnotu d.
(1) vrchol v nen´ı koˇren a f (otec(v)) ≤ f(v) − d, pak zmenˇs´ıme ohodnocen´ı prvku reprezentovan´eho vrcholem v a skonˇc´ıme;
(2) vrchol v je koˇren, pak zmenˇs´ıme ohodnocen´ı vrcholu v a pokud po f (v)−d < f(w), kde na w je koˇren stromu s nejmenˇs´ım ohodnocen´ım, m´ame na nˇej ukazatel, pak zmˇen´ıme tento ukazatel, aby ukazoval na vrchol v a skonˇc´ıme;