Király Zoltán
el®adásai alapján
lejegyezte: Susztár Zoltán
2.2 verzió
1. Alapvet® adatszerkezetek 4
1.1. Adatstruktúrák tervezése . . . . . . . . . . . . . . . . . . . . . . 4
1.4. Gráfok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3. Kupac 16
5. Amortizációs elemzés 37
5.1. Konvex burok keresése . . . . . . . . . . . . . . . . . . . . . . . . 37
6. Fejlettebb kupacok 39
6.1. Fibonacci kupac . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2
6.3. r-kupacok . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
7. Szótárak 53
7.1. Bináris keres®fa . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
7.3. B-fák . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
8. Hashelés 71
8.1. Hash függvények . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
9. Geometriai adatstruktúrák 78
9.1. Egy dimenziós feladatok . . . . . . . . . . . . . . . . . . . . . . . 79
9.4.1. Szakasz-fa . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
3
1. Alapvet® adatszerkezetek
Specikáció :
4
Minden elem két részb®l áll : egy mutatóból (pointerb®l), amely a követ-
kez® elem memóriacímét mutatja, valamint egy, az adato(ka)t tartalmazó
részb®l.
A lista els® elemére a listafej mutat, a lista utolsó elmének mutatója pedig
nem mutat sehová (nil mutató).
ciklikusan láncolt listával, ahol az utolsó elem pointere nem nil, hanem a
legels® elemre mutat,
listafej
nil
M¶veletek :
Új, üres sor létrehozása (S névvel n méret¶t) : Újsor(S, n)
5
1. Ha n fels® becslés az S←v m¶veletek számára :
ELEJE,VÉGE : pointer
1 n
ST 3 6 1
ELEJE
VÉGE
Újsor(S, n) :
Újtömb(ST,n)
ELEJE :=1 ; VÉGE :=0
S ← v:
VÉGE++
ST(VÉGE) :=v
u ← S:
u :=ST(ELEJE)
ELEJE++
1.4. Gráfok
Cél : adatstruktúra egy V = {1,2, . . . n} csúcshalmazú gráf tárolására. (Ha a
gráfunk nem ilyen módon adott, akkor feltesszük, hogy létezik egy olyan bi-
jektív függvényünk, ami ilyen csúcshalmazúvá számozza át és vissza a gráf
csúcsait.)
6
j
i
a ij
M¶veletek :
Megjegyzés :
Multigráf (olyan gráf, amelyben lehetnek hurokélek is, és a csúcsok közt több
párhuzamos él is mehet) :
Súlyozott gráfok :
Két esetet különböztetünk meg :
7
2. Éllista : Egy L tömbben tároljuk a csúcsokból kiinduló éleket felsoroló
láncolt listák listafejeit.
L
1
i 2 5 8 nil
n
LISTAFEJEK
M¶veletek :
Megjegyzések :
Az élfelsorolás (általában a leggyakrabban használt) m¶velet ideje kis fok-
szám esetén sokkal jobb, mint a szomszédsági mátrixnál.
8
Megfordított gráf generálása : végigmegyünk az éleken és egy új éllistába
átmásoljuk a fordítottjukat, ez O(e) id®ben megoldható.
i 2 5 8 0 0 0
n
D megválasztása :
Nyereség :
Veszteség :
9
Tárhelyet veszthettünk is : a tárhely mérete n× maxfok, n× átlagfok he-
lyett (és ez még a jobb eset : ha ismerjük ∆-t, ha ∆-ról nem tudunk semmit,
akkor n × (n + 1) hely kell).
M¶veletek ideje : Ugyanaz, mint az éllista esetén, s®t, egy kicsit még gyorsabb
is, mivel nem kell pointerekkel dolgoznunk.
Összefoglalva : ez a megoldás a gyakorlatban is egy jó megoldásnak tekinthet®,
ha vagy ismerünk egy n-nél kisebb fels® korlátot ∆-ra, vagy a tárfoglalás nem
nagyon érdekel minket (hiszen az egy csúcsból kiinduló éleket itt is fel tudjuk
sorolni fokszám id®ben).
a f
Fák tárolása :
Éllista
Prüfer kód : Egy n csúcsú gráf esetén n − 2 darab szám (abban az eset-
ben, ha a gráf csúcsai 1-t®l n-ig számozottak). Ez az n − 2 darab szám
bijektíven (F fa ↔ a1 , a2 , . . . an−2 , ahol 1 ≤ ai ≤ n) írja le a fát. Ez a
tárolás nagyon alkalmas véletlen fák generálására (ami egyébként nem egy
egyszer¶ feladat).
Szélességi keresés esetén egy adott pillanatban minden egyes csúcs 3 féle álla-
potban lehet :
10
c) Látott és átvizsgált
Az algoritmus :
INIT :
Újsor(S, n) ; Újtömb(L, n)
FOR i := 1 . . . n L(i) := 0
L(1) := 1 ; S ← 1 (látott, de nem átvizsgált)
WHILE S 6= ∅
u←S
FOR uv ∈ E
IF L(v) = 0 THEN L(v) := 1; S ← v
Ez az algoritmus magában nem ad outputot, csak végigmegy a gráf 1-es
csúcsból elérhet® élein.
Minden élszámra tudunk olyan gráfot konstruálni, hogy ennél kevesebb olva-
sással ne legyen eldönthet® a gráf összefügg®sége. Legyen G1 és G2 két egyforma,
11
tetsz®leges összefügg® gráf, az inputnak a két komponense. Ha nem olvassuk vé-
gig legalább az egyiknek az összes élét, akkor G1 és G2 egy-egy nem végigvizsgált
csúcsa közé berakhatunk egy új élet (az éllistáik végére), ezt az algoritmus nem
veszi észre.
Bizonyítás : A G gráf legyen olyan, hogy az els® n/2 csúcs egy komponensbe
tartozik, majd minden ezt követ® csúcs izolált. Ekkor az els® komponens után
n/2 + 1 lépés az els® 0 megtalálása, majd n/2 + 2, és így tovább.
Az algoritmus :
INIT :
Újsor(S, n) ; Újtömb(L, n)
FOR i = 1...n L(i) := 0
k := 0
FOR i = 1...n
IF L(i) = 0 THEN k + + ; L(i) := k ; S ← i
WHILE S 6= ∅
u←S
FOR uv ∈ E
IF L(v) = 0 THEN L(v) := k ; S ← v
12
Lépésszám (éllistás tárolásnál) : O(n + e).
Az algoritmus :
INIT :
Újsor(S, n) ; Újtömb(L, n) ; Újtömb(p, n) ; Újtömb(SZ, n)
FOR i = 1...n
L(i) := 0 ; p(i) := i ; SZ(i) := 0
k := 0
FOR i = 1...n
IF L(i) = 0 THEN k + +, L(i) := k ; S ← i
WHILE S 6= ∅
u←S
FOR uv ∈ E
IF L(v) = 0 THEN L(v) := k ; S ← v ; p(v) := u
SZ(v) := SZ(u) + 1
13
1. tulajdonság :
u x v
SZ: 3 5 4
2. tulajdonság :
u x v
SZ: 4 3 5
Ekkor is xav betétele el®tt is benne volt a sorban, ami ellentmond annak,
hogy u kivétele el®tt teljesült az 1. tulajdonság.
*
v
14
1. Nem lehet uv típusú (lásd az ábrán) él a gráfban, mivel amikor u-t kivettük
a sorból v még nem lehetett benne a sorban, így u átvizsgálása során be
kellett kerülnie eggyel nagyobb szintszámmal.
d(1,x*)
x*
15
u v
3. Kupac
16
Gyökeres fa, melynek csúcsaiban rekordok helyezkednek el.
Az i. csúcs bal ának kulcsa A(2i)-ben lesz, jobb áé pedig A(2i + 1)-ben.
Az i. csúcs szül®jének kulcsa A(bi/2c).
Ezenkívül még tárolunk egy VÉGE pointer (számot), mely megadja, hogy
pillanatnyilag hány elem van a kupacban.
Példa :
4 5
6 7 8 9
12 10 15
A: 2 4 5 6 7 8 9 12 10 15
17
M¶veletek :
Újkupac(A, n) : egy új, üres kupacot hoz létre (n az egy id®ben a kupacban
szerepl® elemek maximális száma).
M¶veletek megvalósítása:
Újkupac(A, n) :
Újtömb(A, n) ; VÉGE:= 0
Beszúr(A, új) :
Ötlet : az adott, hogy hová kell felvenni egy új levelet, oda berakjuk. A kupac
tulajdonság csak egy él mentén romolhatott el. Ezen él mentén javítjuk a kupac-
tulajdonságot, ekkor felette egy másik él mentén romolhat el, így ismételjük,
amíg mindenhol helyre nem áll (lehet, hogy egészen a gyökérig el kell mennünk).
Beszúr(A, új) :
VÉGE++
A(VÉGE) :=K(új)
FELBILLEGTET(VÉGE)
FELBILLEGTET(i):
AA := A(i) ; BB := B(i)
WHILE i > 1 && A(bi/2c) > AA
A(i) := A(bi/2c)
B(i) := B(bi/2c)
C(B(i)) := i
i := bi/2c
A(i) := AA
B(i) := BB
C(BB) := i
Lépésszám : A fa mélysége blog nc, amib®l következik, hogy a FELBILLEG-
TET lépésszáma O(log n).
18
Bizonyítás : Úgy tekintjük, hogy mindig i és szül®je tartalmát felcseréljük
egy-egy lépésben. Állítás : mindig csak i és a szül®je közti él mentén lehet baj
a kupac-tulajdonsággal. Ez kezdetben igaz. Ha i gyökér, vagy szül®jének kulcsa
kisebb-egyenl®, akkor itt sincs baj, tehát kész vagyunk. Különben csere után
ezen él mentén a kupac-tulajdonság helyreáll, és mivel a szül®ben lév® kulcs
csökken, a másik gyereke felé men® él sem romlik el, tehát csak az új i és szül®je
közötti élen lehet baj.
Mintörlés(A) :
CSERE(A(1), A(VÉGE)) ; VÉGE−−
LEBILLEGTET(1)
Return(A(VÉGE+1))
LEBILLEGTET(i):
AA := A(i) ; j := 2i + 1
WHILE j ≤ VÉGE
IF A(j − 1) < A(j) THEN j − −
IF A(j) < AA THEN A(i) := A(j); i := j; j := 2i + 1
ELSE j :=VÉGE+2
j−−
IF j ≤VÉGE && A(j) < AA THEN A(i) := A(j); i := j
A(i) := AA
Lépésszám : O(log n)
Kulcs-csökk(K , elem, ∆) :
i := C(elem)
A(i) := A(i) − ∆
FELBILLEGTET(i)
Lépésszám : O(log n)
19
Alkalmazások:
Az algoritmus:
az adatok betöltése tetsz®legesen az A tömbbe.
FOR i = n/2 . . . 1(−1)
LEBILLEGTET(i)
n n n 1 2 3
2 ·0+
4 · 1 + 8 · 2 + . . . + 1 · dlog ne ≤ n · ( 4 + 8 + 16 + . . .)
a := ( 14 + 82 + 163
+ . . .), könnyen láthatóan ez a sor abszolút konvergens,
a 1 2 3 1 2 3
ezért az a szám létezik. Ekkor a −
2 = ( 4 + 8 + 16 + . . .) − ( 8 + 16 + 32 + . . .) =
1 1 1 1
= ( 4 + 8 + 16 + . . .) = 2 =⇒ a = 1
Azaz legfeljebb n darab lebillentés kell, így O(n) elemi lépés lesz a lépésszám.
20
szükség lesz rá ezt a konstanst növelni is fogjuk az elemzés során (ez nem fog
gondot okozni, mert a nagyobb konstansba beleférnek a növelés el®tti kisebb
konstansok is).
keresése
Megjegyzés : persze ha azt is gyeljük, hogy T -ben mikor lesz n−1 él, akkor
már meg is állhatunk.
Bizonyítás :
e1 e2 e3
T: + - +
+/- jeleket teszünk aszerint, hogy az adott él benne van-e T -ben (T az algorit-
mus által adott fa).
21
1. eset (−/+) :
ei
T: -
T*: +
2. eset (+/−) :
ei
T: +
T*: -
2. Állítás. j > i.
Következmények :
22
Bizonyítás : T ∗ -hoz a sorrend megválasztása :
Az azonos költség¶eket úgy rakjuk sorba, hogy a T ∗ -ban szerepl® élek le-
gyenek el®l. Az el®z® bizonyítást végiggondolva könny¶ látni, hogy ekkor az
algoritmus éppen T ∗ -ot adja.
A) megoldás : A tömbbel.
1 n
A H2 H2 H2 H2
INIT : FOR i := 1 . . . n
A(i) := i
HOLVAN(i) : Return(A(i))
Lépésszám : O(1).
DISZJUNKT-UNIÓ(H1 , H2 ) :
FOR i := 1 . . . n
IF A(i) = H2 THEN A(i) := H1
Lépésszám : O(n)
A II. FÁZIS összlépésszáma : O(e + n2 ) = O(n2 ).
Megjegyzés : S¶r¶ gráfokra jó megoldás.
23
L : a halmaz következ® elemére mutató pointereket tároljuk
K : K(i) az i. halmaz els® eleme
M : M (i) az i. halmaz mérete
3 6 8 20
A 1 1 1 1
L 6 8 20 0
INIT :
FOR i := 1 . . . n
A(i) := i; L(i) := 0; K(i) := i; M (i) := 1
HOLVAN(i) : Return(A(i))
DISZJUNKT-UNIÓ(H1 , H2 ) :
IF M (H1 ) < M (H2 ) THEN H1 ⇐⇒ H2
(felcseréljük a halmazok neveit =⇒ H1 lesz a nagyobb méret¶)
M(H1 ) := M(H1 )+M(H2 )
(a H2 végére f¶zöm a H1 -et, hogy ne kelljen végigmenni H1 -en.)
i := K(H2 )
WHILE L(i) 6= 0
A(i) := H1 ; i := L(i)
A(i) := H1
L(i) := K(H1 )
K(H1 ) := K(H2 )
A Lépés konstansát úgy állítjuk be, hogy egy unió annyi Lépés legyen, mint
a kisebbik halmaz mérete.
24
Strigulázás :
1 i n
1. sor (lépés)
2. sor (lépés)
3. sor (lépés)
Bizonyítás : Minden csúcs el®ször egy egy elem¶ halmazban volt, ezután min-
den strigula behúzásakor egy legalább kétszer akkora méret¶be kerül (hiszen a
kisebbik halmaz elemeinél húzunk strigulát). Így log n strigula után egy n ele-
m¶be kerül, tehát készen vagyunk.
Nem biztos, hogy végig kell menni az összes elemen, ha szerencsénk van,
a legkisebb n−1 élet elég ismerni, tehát a kupac segíthet.
25
H1
H1
H2
H2
H1
26
Ha r(H1 ) > r(H2 )
H1
H2
Ha r(H1 ) = r(H2 )
H1 H2
Kitér® :
Egy csúcs (v ) mélysége : a gyökérb®l a v -be vezet® út hossza.
27
Módszerek:
Útrövidítés:
Útfelezés:
28
Az útrövidítés és az útfelezés elemzése
A Kruskal algoritmus n−1 darab DISZJUNKT-UNIÓ és m = 2e darab
HOLVAN m¶veletet végez. Azt fogjuk elemezni, hogy összesen hány lépésben
valósíthatjuk ezt meg.
3. Állítás. r(v) az elején 0 és monoton n®. Ha v nem gyökér egy adott pilla-
natban, akkor sose lesz az, és az r(v) már soha többé nem változik.
Bizonyítás :
DISZJUNKT-UNIÓ m¶velet : Ha a kisebb rangút kötöttük be a nagyobb alá,
akkor teljesül az állítás. Egyenl® rangúaknál szintén teljesül az állítás, mivel
ekkor az új gyökér rangját növeljük.
Bizonyítás :
1 pontú fára teljesül az állítás.
DISZJUNKT-UNIÓ : különböz® rangúak esetén nyilván teljesül. Egyenl® ran-
gúnál : mindkét fában legalább 2r(x)−1 darab elem van, a kötés után legalább
r(x)−1 r(x)
2·2 =2 lesz.
29
Rangcsoportok:
0 1 2 3 4 5 16 17 65536
R0 R1 R2 R3 R4
Elemzés:
DISZJUNKT-UNIÓ : 1 Lépés
Például :
5 Lépés
30
Az i. HOLVAN m¶veletnél a strigulázási szabály :
Csak akkor kezdünk el strigulákat húzni egy csúcs mellé, ha már nem
gyökér.
Strigulák összeszámolása:
N (g) : jelentse azt, hogy maximálisan hány csúcs lehet a g -edik rangcsoportban.
T (g)
X n n 1 1 n n
N (g) ≤ ≤ T (g−1)+1 (1 + + + . . .) = T (g−1) = .
2r 2 2 4 2 T (g)
r=T (g−1)+1
31
Összefoglalva: g rangcsoportbeli csúcsok mellé összesen legfeljebb T n(g) ·(T (g)−
− T (g − 1)) ≤ n strigula kerülhet.
Ez igaz g = 0-ra is, mivel legfeljebb n darab csúcs lehet a 0. rangcsoportban és
a 0-s rangcsoportú csúcsok mellé csak 1 strigula kerülhet.
Így összesen a csúcsok mellé legfeljebb G(n) · n strigula került.
P M
S
min
T : aktuális fa
S : T-nek a csúcshalmaza
P := {v ∈ V − S | ∃uv ∈ E, u ∈ S}
M := V − S − P
Egy adott lépésnél az M -beli csúcsokkal nem foglalkozunk.
A P -beli csúcsokra két dolgot tartunk nyilván :
32
p(v) := argmin{c(uv) | u ∈ S} - ha ®t kötöm be, melyik csúcshoz kell
kötni (ha több ilyen csúcs is van, akkor közülük az egyik)
Az algoritmus:
P := {1}; S := ∅; M := V − {1}; T := ∅
INIT :
K(1) := 0; p(1) := 1
WHILE P 6= ∅
v legyen a P -ben minimális K(v) érték¶ csúcs
S←v←P
IF p(v) 6= v THEN T := T + {p(v), v}
FOR vu ∈ E
IF u ∈ P && c(vu) < K(u) THEN K(u) := c(vu); p(u) := v
IF u ∈ M THEN K(u) := c(vu); p(u) := v; P ← u ← M
Lépésszám:
Szomszédsági mátrix esetén : O(n2 ) (láttuk a szélességi keresésnél, hogy ennél
gyorsabban nem is lehet).
Éllistával, kupacokkal :
Megjegyzés : ritka gráfok esetén ez sokkal jobb, mint az O(n2 ), de még javítani
fogunk rajta.
33
S: a leveg®ben lév® gyöngyszemek.
M: a többi csúcs.
Példa :
2
-2
Az algoritmus:
P := {1}; S := ∅; M := V − {1}
INIT :
K(1) := 0; p(1) := 1
WHILE P 6= ∅
v legyen a P -ben minimális K(v) érték¶.
S←v←P
FOR vu ∈ E
IF u ∈ P && K(v) + c(vu) < K(u) THEN
K(u) := K(v) + c(vu); p(u) := v
IF u ∈ M THEN K(u) := K(v) + c(vu); p(u) := v; P ← u ← M
34
P M
S
r
h
>=0
Indirekt tegyük fel, hogy létezik ennél rövidebb Q út, ekkor az indukciós fel-
tevés szerint ez nemS -út, legyen az els® P -beli csúcsa w 6= r. Ekkor r deníciója
miatt K(r) ≤ K(w), és így az indukciós feltevés miatt a Q út s-t®l w -ig terjed®
része nem rövidebb, mint K(r) = r -be vezet® legrövidebb S -út hossza. Mivel
az élhosszak nemnegatívak, a Q út w -t®l r -ig terjed® része is nemnegatív, tehát
összesen Q hossza legalább K(r), ami ellentmond Q választásának.
13. Tétel. Az x csúcsba vezet® egyik legrövidebb út (hátulról el®re állítjuk el®) :
s, . . . , p(p(x)), p(x), x.
Megjegyzések :
35
Irányított gráfok esetén, ha bármely irányított kör nemnegatív, akkor van
másik algoritmus (Bellman-Ford), amely helyes és polinomiális, de las-
sabb : O(e · n).
Viszont aciklikus irányított gráfok esetén negatív élsúlyra is van kicsit
egyszer¶bb, O(e) idej¶ algoritmus, ezt használják pl. a PERT módszerben.
Elemzés
Ugyanúgy, mint a Prim algoritmusnál, tehát szomszédsági mátrix esetén
O(n2 ) a lépésszám, éllista esetén, ha valamilyen kupacot használunk, akkor pe-
dig legfeljebb n darab Beszúrás, n darab Mintörlés, és e darab Kulcs-csök kell.
36
Mi vajon a legjobb d? Erre általában nincs egyértelm¶ válasz, az egyes m¶-
veletek gyakoriságától függ.
n db Beszúrás, Min-törlés
e db Kulcs-csökkentés
n · d · logd n = e · logd n
e
d =
n
lem
d∗ := max(2, )
n
-et érdemes használni, mert d-nek egésznek kell lennie és nem akarunk 1-et
alapnak.
Így a lépésszám O(e · logd∗ n). Ez ritka gráf esetén (ha e ≈ c · n) nem nagyon
segít, de s¶r¶nél igen :
5. Amortizációs elemzés
37
pozitív irányú bejárás sorrendjében).
F tömb
(x2,y2)
(x k,yk)
A tömb
Megoldás :
I. rendezzük a pontokat xi -k szerint (x1 < x2 < . . . < xn )
Id® : O(n · log n)
II. Egy adott ciklusban tudjuk az p1 , . . . , pi−1 pontok konvex burkát, külön
tároljuk balról jobbra rendezetten az F fels® és az A alsó ívet.
F OR i = 2 to n
Felez® kereséssel az alsó és a fels® íven végigmenve megkeressük az ug-
rópontot (az utolsó olyat, ami még az p1 , . . . , p i halmaz konvex burkán is rajta
van)
A és F további részét elfelejtjük, majd végükre rakjuk pi -t.
Megjegyzés : F (j) az ugrópont, ha az F (j − 1) és F (j) pontokat összeköt®
egyenes pi felett megy, de az F (j) és F (j + 1) pontokat összeköt® egyenes már
alatta.
Id® : 1 pont hozzáadása legfeljebb O(log n), így az összid® : O(n · log n).
Összefoglalva : síkban a konvex burok keresés O(n·log n) id®ben megoldható.
Itt is érdemes a második fázist gyorsítani (pl. lehet, hogy x szerint rendezve
kaptuk a pontokat).
38
P P P
Így i AIi = i T Ii + PT − P0 ≥ i T Ii .
Tehát az amortizációs id® egy fels® becslést fog adni a m¶veletek összidejére.
6. Fejlettebb kupacok
Tárolás:
39
Minden elemhez 4 pointert tárolunk : szül®je, bal testvér, jobb testvér, egy
gyereke (mindegy, hogy melyik gyerek : ®k is ciklikusan két irányban körbe
vannak láncolva, így gyorsan megtalálhatjuk ®ket).
M¶veletek :
Beszúrás(új) :
új elem
Id® : O(1).
Mintörlés :
M IN := H , a végén Return(M IN )
I. fázis : H gyermekeit gyökeresítjük és a szül® pointereiket nil-re állítjuk.
II. fázis : Amíg létezik 2 azonos rangú gyökér, addig LIN K m¶velettel
összekapcsoljuk ezeket.
40
III. fázis : végigmegyünk a gyökereken és a minimális kulcsú gyökérre ál-
lítjuk H -t.
Az algoritmus:
FOR i = 0...R
T (i) := nil
FOR v ∈ gyökerek
w := v
WHILE T (r(w)) 6= nil
w := LIN K(w, T (r(w)))
T (r(w) − 1) := nil
T (r(w)) := w
Id® : Ha a Lépésben a konstanst 2-szeresére vesszük, akkor
T I = O(log n) + #LIN K.
A Fázis végén legfeljebb R+1 darab gyökér marad. (Minden lehetséges
ranghoz legfeljebb 1.)
A LIN K -elések után az alábbi alakú ún. kanonikus fák (vagy binomiális
kupacok) keletkeznek (mindaddig, míg csak Beszúrás és Mintörlés m¶veleteket
végeztünk)
41
1. rangú 2. rangú 3. rangú
Kulcs-csökk :(H , v , ∆) :
Levágjuk v -t a szül®jér®l és gyökeresítjük (bef¶zzük a gyökerek listájába),
majd :
K(v) :=K(v) - ∆
IF K(v) < K(H) THEN H := v
Látszólag készen vagyunk, de van egy nagy baj : Így nem marad igaz, hogy
a rang legfeljebb R = O(log n).
Szeretnénk : ha r(v) = r, akkor v -nek van legalább cr (c > 1) leszármazottja
(ami persze max. n lehet). Ez Kulcs-csökk nélkül még teljesülne, de így nem
teljesül : ha minden unokára csinálnak egy-egy Kulcs-csökk m¶veletet, akkor
v -nek saját magán kívül csak a gyerekei maradnak meg leszármazottnak, míg
rangja nem változik :
42
Megoldás : m(v) jelz®bit használata :
0 0
v
1 1
1
1 1
Kulcs-csökk :(H , v , ∆) :
Levágjuk v -t a szül®jér®l és gyökeresítjük (bef¶zzük a gyökerek listájába),
majd :
K(v) :=K(v) - ∆
IF K(v) < K(H) THEN H := v
T I : k Lépés
∆P ≤ −2(k − 1) + k + 2 = 4 − k .
43
k: új gyökerek
AI = TI + ∆P ≤ 4.
y1 y2 yr(x)
Bizonyítás :
yi
y1 yi-1
S0 = 1
S1 = 2
k−2
16. Tétel.
X
Sk ≥ Si + 2
i=0
Bizonyítás :
44
x
y1 y2 yi yk
S0 Si-2 Sk-2
√ !k √ !k
5+1 5+1
Fk+2 ≥ , azaz : Sk ≥
2 2
Emlékeztet® n jelöli a kupacban szerepl® elemek maximális számát. Tehát
bármely v elemnek legfeljebb n leszármazottja lehet ⇒ r(v) ≤ log“ √5+1 ” n ≈
2
n db beszúrás
n db mintörlés
e db kulcs-csökkentés
összes ideje : O(n log n + e).
Ebb®l következik :
Megjegyzések :
45
FIZETÉS BANK
Kell : A bank pénze ne mehessen le negatívba. Ezt pont azzal biztosítjuk, hogy
megköveteljük, hogy P ≥ 0 legyen, ugyanis egy adott pillanatban a bankban
lev® pénz éppen az aktuális potenciál.
nagy szorzók vannak (1,44) és az 1 Lépés is sok kis elemi m¶veletb®l áll.
v
v
a
a b c b
c
Bináris fa.
Az egyetlen gyökérnek (ami H -nak felel meg) nem lehet jobb gyereke.
46
1 bit : bal vagy jobb gyerek.
47
1. pointer :
2. pointer :
Gyökérben nil.
Könny¶ Hf : egy eredeti pointer szerinti lépéshez így két lépés és egy harma-
dik kiolvasás-vizsgálat kell.
LIN K m¶velet :
y
x 4 y 3 x
a b LINK a b
A B A B
Id® : O(1).
Kupacm¶veletek :
Kulcs-csökk :
kivágjuk az elemet
csökkentjük a kulcsot
majd LINK.
48
v
T I = O(1).
Mintörlés :
vágás
8
1
7
2
6
3
5
v
4
49
6.2.1. A párosítós kupacok legjobb változata
Ötlet : Még lustábban. Nem jó kicsiket nagyobbakkal LINK-elni. Ezt tipikusan
a Beszúrás és Kulcs-csökk m¶veleteknél tesszük. Ezért ennél a két m¶veletnél
LINK-elés helyett egy külön segédterületre rakjuk ®ket.
segédterület
Beszúrás Beszúrás . . .
Mintörlés :
6.3. r-kupacok
Dijkstra algoritmushoz : Feltesszük, hogy az élek hossza a [0, C] tartománybeli
egészek ⇒ a kulcsok a [0, (n − 1)C] tartományban lesznek.
50
u1 u2 u3 u4 u5
B1 B2 B3 B4 B5
Vödrök :
range(Bi ) = [ui−1 + 1, ui ].
Kezdetben :
u0 = -1
ui = 2i−1 − 1
uB = nC (ebbe a vödörbe biztosan belefér minden elem)
range(B1 ) = [0]
range(B2 ) = [1]
range(B3 ) = [2, 3]
range(B4 ) = [4, 5, 6, 7]
.
.
.
M¶veletek :
Beszúrás :
FOR j := B . . . 1(−1)
IF uj−1 < K(v) THEN v → Bj és kilépünk a ciklusból.
K(v) := K(v) − ∆
IF másik vödörbe THEN kivesszük, elindulunk balra és megkeressük a jó
vödröt.
Mintörlés :
51
Különben legyen Bj az els® nem üres vödör. Végignézzük a Bj vödör
minden elemét. Legyen v a minimális kulcsú, dmin := K(v).
Átcímkézzük ui -ket :
u0 := dmin − 1
u1 := dmin
ui := min(ui−1 + 2i−2 , uj ), ha i = 2, . . . , j − 1.
Ezután Bj minden elemét egyesével balra mozgatva berakjuk a neki meg-
felel® vödörbe, kivéve v -t, amelyet törlünk.
19. Tétel. Ezután Bj minden elemének a helye valamilyen i < j -re Bi lesz.
Amortizációs elemzés
X
A potenciál : P = b(v), ahol b(v) a v -t tartalmazó vödör sorszáma.
v∈kupac
Egy Lépés legyen (el®ször) 1 elem eggyel balra átrakásának ideje (kivesszük,
ellen®rizzük, hogy oda való-e, berakjuk).
M¶veletek:
Beszúrás(v) : T I = (B + 1 − b(v)) + 1
(B + 1 − b(v)) : megkeressük, hogy hová kell beszúrni az elemet.
1 : beszúrjuk.
∆P = b(v)
Így AI = B + 2.
52
j : ui -k átcímkézése,
utolsó tag : balra pakolások ideje (1+ a v kihagyása).
Megjegyzés
X :
X X
T I ≤ j +|Bj |/2+1/2+(1/2)· j −buj (u) ≤ j +1+ j −buj (u)
u∈Bj ,u6=v u∈Bj ,u6=v
X
Mivel ∆P = −j − j − buj (u) , ezért AI ≤ 1.
u∈Bj ,u6=v
Ezzel a kupaccal a Dijkstra O(e + n · log log min(n, C)) idej¶ lesz.
7. Szótárak
Legyen adott egy U univerzum és egy ezen a halmazon értelmezett < rendezés.
M¶veletek :
Keresés(x) :
Könnyített : x ∈?S
53
Nehezebb : keressük meg x-et ha x ∈ S, különben pedig N IN CS .
Ha egy szótár csak ezt az egy m¶veletet tudja megvalósítani, akkor statikus
szótárnak nevezzük.
Beszúrás(x) :
Törlés(x) : ha x ∈ S, akkor S := S − x.
Ha mindhárom m¶velet megoldott, akkor az adatstruktúra szótár törléssel.
min(S)
max(S)
Tólig(S,a,b) : = {x ∈ S | a ≤ x ≤ b}
Fésül(S1 ,S2 )
Olvaszt(S1 ,a,S2 ) : Tudjuk, hogy S1 < a < S 2 és S := S1 + a + S2 .
Szétvág(S,a) : Szétvágja S -et olyan S1 és S2 -re, hogy S1 < a < S 2 .
x<?T[n/2]
i h
x<?T[n/4]
i h
. . .
. . . . . .
54
7.1. Bináris keres®fa
Ez az el®z®vel lényegében ekvivalens.
u1
i h
u2 u3
i h
s
. . .
Keresés(x) :
Legyen r a gyökér.
REPEAT
IF x ≤ u(r) és ∃ bal(r) THEN r := bal(r)
IF x > u(r) és ∃ jobb(r) THEN r := jobb(r)
IF r levél THEN
IF x = u(r) THEN RETURN(r)
ELSE RETURN(x ∈
/ S)
ELSE RETURN(x ∈
/ S).
Megjegyzés : A levelekben balról jobbra haladva S elemei rendezve vannak.
s'
55
A bels®-és küls® tárolású fák összehasonlítása :
Küls® Bels®
Memória ∼ 2n kulcs n kulcs
Mélység dlog ne dlog(n + 1)e − 1
Keresés dlog ne összehasonlítás dlog ne − 1 összehasonlítás, de 3 irányú !
Megjegyzés :
Adottak :
ai -t pi valószín¶séggel keressük.
56
Feladat : Minimális költség¶ bináris keres®fa konstrukciója, azaz olyan T , amely-
re c(T ) minimális.
ak
T1 T2
Inicializálás :
Ti,i = ∅ ; ci,i = 0 ; wi,i = qi .
Nekünk a T0,n fát kell megkeresni. Vegyük észre, hogy ha tudnánk, hogy
ri,j = k , akkor a szuboptimalitás elve miatt a Ti,j fa gyökerének bal részfája
Ti,k−1 , jobb részfája pedig Tk,j lesz. Ezért ekkor a költsége ci,j = (ci,k−1 + qi +
+ pi+1 + . . . + qk−1 ) + pk + (ck,j + qk + pk+1 + . . . + qj ) = ci,k−1 + ck,j + wi,j lesz,
mivel a Ti,j fában minden csúcs mélysége eggyel nagyobb, mint a Ti,k−1 ill. a
Tk,j fákban. Vegyük észre, hogy a költségben wi,j állandó, nem függ a k -tól.
Ezek alapján könnyen készíthetünk egy rekurzív algoritmust :
R(i, j) : c0i,j := ∞
FOR k := i . . . j
C1 := R(i, k − 1)
C2 := R(k, j)
0 0
IF C1 + C2 < ci,j THEN ci,j := C1 + C2; ri,j := k
0
RETURN(ci,j := ci,j + wi,j )
57
Amit már egyszer kiszámoltunk, azt feljegyezzük, hogy ne kelljen még
egyszer kiszámolni, valamint
a5
a4 a6
q3 q4 q5 q6
FOR l = 1...n − 1
FOR i = 1...n − l
j := i + l
ci,j := wi,j + mini<k≤j (ci,k−1 + ck,j )
ri,j := argmini<k≤j (ci,k−1 + ck,j )
Id® : O(n3 ).
Beszúrás(x) : Keresés(x), ha x ∈
/ S, megkapjuk az r ktív levelet és berakjuk
oda x-et. Küls®nél a keresés vagy egy levélben áll le, akkor ahelyett egy bels®
csúcs kell, az eredeti levél és a beszúrandó lesznek a gyerekei. Vagy pedig egy
olyan x csúcsban, melynek pl. nincs jobb gyereke, de a keresés jobbra lépne ;
ekkor x új jobb gyerekébe rakjuk az új elemet.
Törlés(x) :
Bels® :
1. eset : Ha x-nek legfeljebb egy gyereke van, akkor a gyereke jön a helyére.
Ekkor az új fa is jó keres®fa lesz.
58
x
y
y
xy
Ami rossz :
59
7.2. 2-3 fák
Tulajdonságok :
Minden levél ugyanazon a szinten lesz. Így n≥2 esetén legfeljebb dlog ne
mélység¶ lesz a fa.
max(u1) max(u2)
u1 u2 u3
Beszúrás(s) :
60
Ha x-nek 2 gyereke volt, akkor beszúrjuk és így 3 gyereke lesz (x-ben
átállítjuk az útjelz®ket).
x1 x2
Id® : O(log n)
Az útjelz®ket mindkét esetben állítgatni kell.
20. Tétel. Ha az új elem (s) beszúrásától max(v) n®tt, akkor v gyökér, vagy
annak csupa-jobb leszármazottja, azaz minden eddiginél nagyobb elemet szúrtunk
be.
Bizonyítás : Ha egy lépésben nem jobbra mentem, akkor az úgy lehetett, hogy ott
s ≤ m1 vagy s ≤ m2 volt. Érdemes a maximális elem értékét külön is eltárolni.
x x1 x2
max(u1) max(u2)
u1 u2 u3
Ennek a maximuma nincs
feljegyezve!
Ekkor nem tudjuk mind a 4 gyereknek a maximumát (most fel kell írnunk). A
hiányzó érték max(x) lesz, de ez is fel van írva a nagyszül®ben, vagy valamelyik
távolabbi ®sben.
61
m2=max(y)
gyökér
max(y)
Törlés(s) :
y x y x
z s z
max(z) fel van írva vagy y -ban, vagy p(x)-ben. Felfelé javítanunk kell
a jelz®táblákat !
62
2. Ha nem létezik, akkor x-et összevonjuk valamelyik testvérével.
y
y
x x
7.3. B-fák
Tulajdonságai :
l m
B
Minden nem-levél csúcsra igaz, hogy :
2 ≤# gyerekek ≤B (kivéve,
l m
B
ha gyökér és ha n< 2 ).
Küls® táraknál használják : Ezek a tárolók 1 olvasás során egy egész lapot
olvasnak be. Az tart sok ideig, míg a fejet a megfelel® lapra pozícionálja a vezér-
lés. Az a cél, hogy minél kevesebb lapot kelljen olvasni ahhoz, hogy megtudjuk,
hogy hol van az az adat, amit a tárolón keresünk. Úgy érdemes B -t úgy meg-
választani, hogy a B−1 útjelz® elférjen egy lapon.
63
f
p p
f
p
Tulajdonságai :
M¶veletek :
Keresés(x) : Ugyanúgy kell megvalósítani, mint egy tetsz®leges bináris fában.
y=P(x) x
x y
C Billentés(x) A
A B B C
Piros-fekete fáknál ez nem mindig lesz jó. Ha y fekete és x piros, és ekkor még
át is kell színezni x-et és y -t, hogy teljesüljön a 3. tulajdonság. Pl. ha a fa alakja
a következ® :
64
y f x f
p p
f y
x
C Billentés(x) A
f
A B B C
Beszúrás(s) : A beszúrás egy fekete szín¶ x ktív levél helyére történik, alatta
létrejön két új fekete ktív levél. Ezt a csúcsot (x-et) pirosra kell színeznünk a
3. tulajdonság fenntartása miatt.
f p
f f
Akkor van probléma, ha a beszúrt x elem y apja piros szín¶ (ha fekete, akkor
készen vagyunk). Ezen belül három esetet különböztetünk meg :
p
x
f f
f p
p p f
y f y
x p x p
Ezután x := p(y) és folytatjuk felfelé az eljárást (ez legfeljebb log n lépést jelent).
2. eset : Ha p(p(x)) = z -nek x bal-bal vagy jobb-jobb unokája.
65
f y
f z
p x p z
y p
f
p
x Billentés(y)
D f
C C
A B D
A B
f z
f z f x
y x p
p
f y y Z
p p p
p x Billentés(x) f Billentés(x)
D
A C D
f
A B A B C D
B C
Törlés(x) : Itt 5 különböz® eset lesz és belátható, hogy legfeljebb log n átszíne-
zéssel és legfeljebb 3 billentéssel megoldható a m¶velet.
Bináris keres®fa,
∀x : |m(bal(x)) − m(jobb(x))| ≤ 1.
66
M¶veletek :
Beszúrás(s) : Beszúrjuk s-et, majd megkeressük a legközelebbi x ®sét, ahol a
3. tulajdonság elromlott ; közben persze a fenti jelz®biteket megfelel®en átállít-
juk. Majd itt egy szimpla vagy egy dupla billentéssel a tulajdonság helyreállít-
ható az alábbi módon :
x y
y x
Bill(y)
C A
A B B C
x s
Bill(s)
y y x
Bill(s)
s
x z
y y x
Bill(z)
z Bill(z)
D
B C
A A D
B C
s
67
7.6. Önkiegyensúlyozó fák (Splay-tree; Sleator és Tarjan)
Itt is bels® tárolású bináris fákat használunk, azonban a kiegyensúlyozottságra
nem teszünk explicit feltételt, amit fent kellene tartani. Helyette id®nként bil-
legtetünk, és majd belátjuk, hogy átlagosan, azaz amortizációs id®ben minden
m¶velet elég gyors lesz azaz O(log n) idej¶.
M¶veletek :
Dbill(x) : Kétfajta Duplabillentést különböztetünk meg.
x
z
y
y
z
x 1. Billentés(y)
D A
2. Billentés(x) B
C
A B C D
x
z
y z
y
x 1. Billentés(x)
D
A 2. Billentés(x) A B C D
B C
Felbillegtet(x) :
WHILE p(p(x)) 6= nil
Dbill(x)
IF p(x) 6= nil THEN Bill(x)
Keresés'(x) :
Keresés(x)
Felbillegtet(x)
68
Beszúrás'(x) :
Beszúrás(x)
Felbillegtet(x)
Törlés'(x) :
z := p(y), ahol y az x megel®z®je
(y = x, ha x-nek legfeljebb 1 gyereke van)
Törlés(x)
Felbillegtet(z)
Potenciál :
x w(x) := x leszármazottainak
súlya : száma (saját magát is beleértve)
x r(x) := blog
rangja :
P w(x)c
A potenciál : P := r(x)
Bizonyítás: Belátjuk minden egyes billent® lépésre, hogy teljesül a fenti állí-
tás megfelel®je. Összeadva ezeket egy teleszkópikus összeget kapunk, amelyb®l
minden tag kiesik, kivéve 1 + 3 · (r(gyökér) − r(x)). A továbbiakban r jelöli a
billentés el®tti, míg r0 a billentés utáni rangot.
AI ≤ 1 + 3 · (r(y) − r(x)).
y x
x y
1. Billentés(x)
C A
A B B C
r r'
69
∆P = r0 (z) + r0 (y) + r0 (x) − r(z) − r(y) − r(x) ≤ 2 · (r(z) − r(x)), mivel
r0 (z) és r0 (y) ≤ r0 (x) = r(z), és r(y) ≥ r(x).
Ha r(z) > r(x) ⇒, ekkor 3 · (r(z) − r(x)) ≥ 2 · (r(z) − r(x)) + 1 ≥ ∆P + T I .
Ha r(z) = r(x) = r (ez az alsó-egészrész miatt lehetséges) ⇒ r(y) = r és
r0 (x) = r.
Elég belátni, hogy r0 (z) < r, mert akkor ∆P ≤ 2r + r0 (z) − 3r ≤ −1, így
AI ≤ 3 · 0, mert ∆P ≤ −1 és T I = 1.
β α
x
z
y
α y
z
x 1. Billentés(y)
A
C
D
2. Billentés(x) B β
A B C D
Ekkor : w(z) = α + β .
Indirekt tegyük fel, hogy r0 (z) = r ⇒ β ≥ 2r . Mivel r(y) = r ⇒ α ≥ 2r ,
r+1 0
innen : α+β ≥2 ⇒ r (x) ≥ r + 1, ami ellentmondás.
3. (b) típusú Duplabillentés :
x
z
α
α y β
y z β
x 1. Billentés(x)
D
A 2. Billentés(x) A B C D
B C
70
Végs® elemzés :
AI(Keresés') ≤ ∆P (Keresés)+∆P (Felbillegtet)+2+T I(Felbillegtet) (mivel
T I(Keresés) belefér a Felbillegtet tényleges idejébe). Így, mivel ∆P (Keresés) =
= 0, ezért AI(Keresés') = O(log n).
AI(Törlés') ≤ ∆P (Törlés) + ∆P (Felbillegtet) + 2 + T I(Felbillegtet) (mivel
T I(Törlés) belefér a Felbillegtet tényleges idejébe). Így, mivel ∆P (Törlés) < 0,
ezért AI(Törlés') = O(log n).
8. Hashelés
√
Születésnap paradoxon : Ha N ≥ ln 4 · M , akkor legalább 21 valószín¶séggel
lesz olyan x 6= y , hogy h(x) = h(y). Ezt ütközésnek fogjuk nevezni.
71
Persze mindenekel®tt az U univerzum elemeit valahogyan természetes szá-
mokra kell leképeznünk. Ez általában könyen megoldható úgy, hogy különböz®
kulcsoknak különböz® számok feleljenek meg. Ezt a továbbiakban feltételezzük,
tehát innent®l úgy tekintjük, mintha U elemei természetes számok volnának.
2. Szorzó-módszer :
n
A o
h(K) = ·K ·M , ahol {} a törtrész, M = 2m és W = 2w alakú.
W
Ezért a W -vel való osztás, a törtrész, az M -el való szorzás és az egész-
rész bitléptetésekkel/levágásokkal gyorsan megvalósítható ; igazából csak
az A·K szorzás kiszámítása igényel lényeges id®t.
A
A megválasztása : az lenne a legjobb választás, ha W = α irracionális lenne
(α < 1).
2α 8α
α
3α
7α
4α 6α
5α
72
8.2. Ütközések feloldása
8.2.1. Láncolt hash-elés
L
0
f(K)=i nil
nil
M-1
LISTAFEJEK
Beszúrás(K) :
Törlés(K) : egyszer¶.
Id® :
c0N : a sikertelen keresés várható lépésszáma, ahol f (K) = i 1
M valószín¶ség-
gel.
1
cN : a sikeres keresés várható lépésszáma, ha minden elemet
N valószín¶ség-
gel keresünk.
N
Emlékeztet® : α= M.
73
M −1 P
X 1 ki X 1 N
Ekkor : c0N = (ki + 1) = + = + 1 = α + 1.
i=0
M M M M
E(ξi ) = c0i−1 cN = E( N1 ξi ) = 1 1
c0i−1
P P P
Ekkor : és
N E(ξi ) = N a várható
érték linearitása miatt.
N N N ·(N −1)
X 1 i−1 1 X i−1 2
Innen : cN =
(1 + ) = 1+ ( ) = 1+ = 1+
i=1
N M N i=1 M NM
N −1 α
+ ≈1+ .
2M 2
egyszer¶,
mindig tudunk új elemet berakni, azaz nem telik be (amíg tudunk helyet
foglalni a memóriában),
könny¶ törölni,
Hátrányai :
74
0
M-1
Keresés : a sorozat szerint sorban keresünk (csak az els® üres helyig kell
keresni)
Megjegyzés :
A nyílt címzés név onnan származik, hogy nincs el®re eldöntve, hogy hová
rakom az egyes elemeket.
h(K)
75
El®ny :
Gyors és egyszer¶.
Hátrányok :
Ha kialakul egy hosszú telített rész (lánc ), akkor nagy annak a valószín¶-
sége, hogy a következ® elem is ebbe a láncba érkezik,
Lépések : cN = 12 (1 + 1
1−α ) és c0N = 21 ((1 + 1 2
1−α ) ).
1 2
α 2 3 0,8 0,9
cN 1,5 2 3 5,5
c0N 2,5 5 13 50,5
K'
K1
törölt
h(K')
76
Osztó-módszer : M 0 és M legyenek ikerprímek és h0 (K) := 1+(b M
K
cmodM 0 ).
0
A +1 azért kell, hogy i · h ne legyen 0.
A*K
h(K) a 1
m m
Lépések : cN = 1 1
α (ln 1−α ) és c0N = 1
1−α .
1 2
α 2 3 0,8 0,9
cN 1,39 1,65 2,01 2,56
c0N 2 3 5 10
77
8.7. Univerzális hash-elés
Ötlet : Vegyünk sok hash függvényt és ezekb®l válasszuk egyet.
9. Geometriai adatstruktúrák
A feladat : Adott egy x térkép és arra vagyunk kíváncsiak, hogy hogyan néz ki
a térkép egy adott környezetünkben. A kérdés, hogy hogyan érdemes tárolni a
térképet, hogy ezt a feladatot gyorsan meg tudjuk valósítani.
78
Feltételezések (egyszer¶sítések) :
ID : O(log n + k)
TÁR : O(n)
FELÉPÍTÉS : O(n · log n)
Megoldás : rendezett tömbben tároljuk a pontokat ; xb -t megkeressük felez®
kereséssel, majd innent®l listázunk, míg xj felé nem érünk.
79
v0 x0,Lb,L j
x x0
80
9.2. Két dimenziós feladatok
III. TÁROLNI : p1 , p2 , . . . pn ∈ R2 pontok, pi = (xi , yi ).
KÉRDÉS : Egy adott [xb , xj ]×[ya , yf ] téglalapba es® pontok felsorolása, azaz
{pi | xb ≤ xi ≤ xj és ya ≤ yi ≤ yf }.
TÁR : O(n · log n) (egy pont minden szinten pontosan egyszer szerepel).
x b keresése x j keresése
? ?
81
A fa mélysége log n, így legfeljebb 2 · log n fontos csúcs van.
ID : O(log2 n + k)
FELÉPÍTÉS : O(n · log n) Hint : rendezzük a pontokat x és y koordináta
id®ben kettészedhet®k.
Megjegyzés :
A cél : O(log n + k) keresési id®, ehhez az kell, hogy a v -nél csak O(1 + kv )
id®t töltsünk.
A 3 10 19 23 30 37 59 62 70 80 100
H nil
B 10 19 30 62 70 80
82
ya -t csak a gyökérnél keressük, utána Hb vagy Hj mutatja meg a "helyét"
(az els® ya -nál nem kisebb elemet).
ID : O(log n + k)
83
Hint a kétszeri kiírás megakadályozására : egyszer¶, de kicsit kényelmetlen
megoldás lehet, ha egyrészt felveszünk egy n hosszú tömböt (n a szakaszok
száma) és egy sort. Ha bármely fázisban megtaláljuk az i. szakaszt, akkor meg-
nézzük, hogy a tömb i. eleme 1-e, ha igen megyünk tovább, ha nem, akkor egyre
állítjuk és i-t berakjuk a sorba. A végén a sorból ki tudjuk íratni az összes
megtalált szakaszt, és közben a tömböt újra le tudjuk nullázni.
yf
ya
84
yf
ya
xj
Bizonyítás : Ha meghívtuk REP ORT (u, K)-t, akkor vagy u gyökér volt, vagy
u része az outputnak, vagy p(u) része az outputnak, tehát k hosszú output esetén
legfeljebb 3k + 1 hívás lesz.
85
rekurzívan y' rekurzívan y'
alatti nem q(v) feletti nem
pontok q(v) pontok
belsõ lelógó
elemek: ezek y
szerint csupa jó
pontok
ya yf
A keresési utak során bejárt csúcsokban tárolt q(v) pontokat egyesével leel-
len®rizzük, hogy benne vannak-e a kérdezett téglalapban. Ezeken kívül minden
más jó pont valamely fontos csúcs alatt lesz. Ráadásul egy v fontos csúcs alatti
minden pont y koordinátája az [ya , yf ] intervallumba esik, így a fontos csúcsok
részfáit már kupacként kezelhetjük, és az el®bb látott módon ki tudjuk írni a jó
pontokat O(1 + kv ) id®ben, ahol most kv az output összes, a v részfájába es®
pontjainak számát jelöli.
ID : O(log n + k)
Ez ugyanolyan gyors, mint a tartomány-fa kaszkádolással, de egyszer¶bb a
megvalósítás és kisebb a tárigény :
TÁR : O(n)
FELÉPÍTÉS : O(n · log n)
86
metsz® ferde szakaszokat. Szimmetria okokból nyilván itt is elég lekérdezni egy
adott függ®leges szakaszt metsz® ferde szakaszokat.
yf
ya
9.4.1. Szakasz-fa
Felbontjuk a számegyenest a végpontok által meghatározott egypontú és nyílt
szakaszokra. Egy-egy ilyen szakaszba azok az x-ek esnek, amelyekre biztosan
ugyanaz a válasz (az ®t tartalmazó intervallumok halmaza).
87
v
-) . () .() .() .
26. Tétel. Egy adott Ij intervallumot a fa egy szintjén maximum kétszer tárol-
juk, így az összes tárigény O(n · log n).
88
x
Int(v)
89