algoritmusok és adatszerkezetek
DESCRIPTION
Algoritmusok és adatszerkezetek. PTE-TTK 2008. ősz. Kilián Imre Software H-7683 Gyűrűfű Cseresznyéskert [email protected]. Kiválasztási/keresési feladat. Legabsztraktabb megfogalmazás: Tábla-Rekord-Mező – Rendezhető típusok sorszámmal indexelhető összetevőkkel, - PowerPoint PPT PresentationTRANSCRIPT
Algoritmusok és adatszerkezetekPTE-TTK 2008. ősz
Kilián Imre Kilián Imre SoftwareSoftwareH-7683 GyűrűfűCseresznyé[email protected]
Kiválasztási/keresési feladat
Legabsztraktabb megfogalmazás:-Tábla-Rekord-Mező – Rendezhető típusok- sorszámmal indexelhető összetevőkkel,- keresés ciklusban (lineárisan)Absztrakt megfogalmazás:-KereshetőTábla-KulcsosRekord-Kulcs- Keresésre önálló eljárás- Kulcs: rendezési relációval
Kulcs
Tábla Rekord Mező
KereshetőTábla
keres(k : Kulcs) : KulcsosRekordKulcsosRekord
TáblaRekord
KereshetőTáblaRekord
{ordered} {ordered}
Rendezhető
<(r : Rendezhető)
(f rom Adatszerkezetek)
LáncoltLista
0..1+következő 0..1
LáncRekordString
(f rom lang)
1
1
+mező
1
1 +kulcs
KereshetőTábla
keres(k : Kulcs) : KulcsosRekordKulcsosRekord
Rendezhető
<(r : Rendezhető)
(f rom Adatszerkezetek)
Konkrét keresési feladat (nem pontos!)
• Keresés időszükséglete (átlagban): Θ(n)• Indexelés időszükséglete (kötött szélességű, sorszámmal indexelt
vektorokban) állandó• Cím szerintitartalom szerinti keresés• Határozatlanságok: téridő, felgyorsulólelassuló műveletek• Megoldás: keresőszerkezetek építése• Alkalmazás: adatbázisokban, fordítóprogramok szimbólumtáblájában
stb.
Még konkrétabban• 0. Milyen gyűjtemény? Halmaz? Csomag? Vektor
• 1. beszúrás. Mi legyen, ha már létezik? Szúrja be újabb példányként is…
• 2. törlés. Mi legyen, ha nem létezik? Semmi. Ilyenkor ne töröljön. Mi legyen, ha több is létezik? Az elsőt törölje ki.
• 3. keresés. Mi legyen, ha több példány is létezik? Az elsőt találja meg. Mi legyen, ha nem található a keresett elem? Adjon hibaeredményt.
Fák (kicsit különböző fogalmak)• Nyílt fa (fa): összefüggő, körmentes, irányítatlan gráf
(nincs kitüntetett csúcs, nincs gyökér)• Erdő: nem összefüggő• Tulajdonságai. Az alábbi állítások egyenértékűek:• 1. G=(E,V) egy nyílt fa• 2. G bármely két csúcsához egyértelműen tartozik egy
őket összekötő egyszerű út• G összefüggő, de bármely élének elhagyása után már
nem az• G összefüggő, és |E|=|V|-1• G körmentes, és |E|=|V|-1• G körmentes, de akár egyetlen éllel is bővítve, már nem
az• Bizonyítások: 12, 23, 34, 45, 56,61
**
*
*
*
*
Fák• Gyökeres fák: egy pont kitüntetett
• x-ben gyökerező fa
• Legyen x gyökér. Az xw út elemeit w megelőzőjének nevezzük. Ha x megelőzője y-nak, akkor y rákövetkezője x-nek.
• Szülő, gyerek, testvér, fokszám
• Fa szintjei, magassága
x
y
v
w
z
u
gyökér
gyökér
Belső pont
Fák• Rendezett fa: ha minden csúcs gyerekei rendezettek
(létezik, értelmezünk, használunk rendezési relációt, akár az elemek feletti rendezés, akár sorbaállítás)
• Kétágú (bináris) fák, amelyek• - vagy nem tartalmaznak csúcsot• - vagy a csúcsai 3 diszjunkt halmazba sorolhatók: a
gyökér, a bal(rész)fa és a jobb(rész)fa, mindketten bináris fák
• A balfa gyökere: bal gyerek, jobbfáé: jobb gyerek• Ha valamelyik részfa üres: hiányzó gyerek• NEM: rendezett fa, melyben a fokszám legfeljebb 2
(azért, mert a mindkét részfa lehet hiányzó)
Fák• K-ágú teljes fák: melyekben nincsenek részben
hiányzó gyerekek/a csúcsok fokszáma vagy 0 (levél) vagy K, ÉS a minden levél magassága egyforma H.
• Tétel: K-ágú teljes fák leveleinek a száma: KH.
• Tétel: K-ágú teljes fák csúcsainak a száma:1+K+K2+…+KN =i=0Σh-1Ki = (Kh-1)/K-1
3
2 7
4 1 5
6
3
2 7
4 1 5
65
5
55 555 5
Nem teljes fa
Teljes bináris fa
Bináris keresőfák• Adatszerkezet, amely a keresést felgyorsítja.• Átlagosan: Θ(log(n)), legrosszabb esetben: Θ(n)• Használat: elsőbbségi sorként, ill. szótárként• Bináris keresőfa tulajdonság: minden v csúcsra:
v.bal<v<v.jobb, ha létezik balfa, ill. jobbfa• Ugyanahhoz a halmazhoz több ilyen fa is építhető
Réka
Csaba
Árpád
Torda
ElődÁlmos Tas
Géza
Csenge
Csilla
Tas
Csaba
Árpád
Torda
Előd
Álmos
Réka
Géza
Csenge
Csilla
Műveletek és megvalósítás
• Futásidő: O(h)• keres(k:Kulcs):KulcsosRekord if k=tartalom.kulcs then return tartalom if k<tartalom.kulcs then return
balfa.keres(k) else return
jobbfa.keres(k)
AlapBinárisFa
tartalom : KulcsosRekord
keres(k : Kulcs) : KulcsosRekordbeszúr(r : KulcsosRekord)töröl(k : Kulcs)
0..1+jobbfa
0..10..1+balfa
0..1
BinárisFa
minimum() : BinárisFamaximum() : BinárisFaelőző() : BinárisFakövetkező() : BinárisFaelőző(k : Kulcs) : BinárisFakövetkező(k : Kulcs) : BinárisFa
Objektumorientált szemlélet
1 1Egyirányú?
• keres(f:BinárisFa,k:Kulcs):KulcsosRekord while f<>NIL és k<>f.tartalom.kulcs do if k<f.tartalom.kulcs then f=f.balfa else f=f.jobbfa return f
Nem objektumorientált (hagyományos) szemlélet
(Nem csak kereső) -Fák bejárása• InorderBejárás() if balfa<>NIL then
balfa.InorderBejárás() print tartalom.kulcs if jobbfa<>NIL then
jobbfa.InorderBejárás()• PreorderBejárás() print tartalom.kulcs if balfa<>NIL then
balfa.PreorderBejárás() if jobbfa<>NIL then jobbfa.PreorderBejárás()
• PosztorderBejárás() if balfa<>NIL then
balfa.PosztorderBejárás() if jobbfa<>NIL then
jobbfa.PosztorderBejárás() print tartalom.kulcs
Fordított lengyel alak képzés
Függvényszerű alak képzése
Szimbólumtábla kiíratás abc-rendben
• minimum():BinárisFa if balfa<>NIL then return balfa.minimum() else return Me
• maximum():BinárisFa if jobbfa<>NIL then return jobbfa.maximum() else return Me
• következő():BinárisFa if jobbfa<>NIL then return jobbfa.minimum()
• következő(k:Kulcs):BinárisFa ez = keres(k) if ez=NIL return NIL ez=ez.következő() if ez<>NIL return ez az = ez.őse while az<>NIL és ez=az.jobb ez=az; az=az.őse return az
Benne van az adatszerkezetben?
HF1: az eljárást megírni „őse” nélkül. (keres
kifejtésével)
HF2: az „előző” eljárást megírni
Beszúrás• Addig keresünk a fában, amíg NIL-hez jutunk.• Beszúr(r:KulcsosRekord)szülő=gyerek=Mewhile gyerek<>NIL do szülő=gyerek if r.kulcs=szülő.tartalom.kulcs then hiba „Már benne van!”, return if r.kulcs<szülő.tartalom.kulcs then gyerek=szülő.balfa else gyerek=szülő.jobbfaif r.kulcs<szülő.tartalom.kulcs then szülő.balfa=new BinárisFa(r)else szülő.jobbfa=new BinárisFa(r)
FaKonstruktor
Az összehasonlítás eredményét meg is
őrizhetjük
Az eljárás üres fára nem működik
Törlés• ha nincs gyereke, akkor töröljük a rámutatót• ha egy gyereke van, akkor a rámutató a gyerekre mutat• ha két gyereke van, akkor kicseréljük vagy a balfa
legnagyobb, vagy a jobbfa legkisebb elemével
Előd
Géza
Csenge
Csilla
Csaba
Árpád
Álmos Előd
Géza
Csenge
Csaba
Árpád
Álmos
Előd
Géza
Csenge
Csilla
Árpád
Álmos
Csilla törlése
Csaba törlése
• törlés(k:Kulcs)csúcs=keres(k)if csúcs.bal=NIL vagy csúcs.jobb=NIL then vág=csúcselse vág=előző(csúcs)if vág.bal=NIL then fia=vág.jobbelse fia=vág.balif fia<>NIL then fia.őse=vág.őseif fia=vág.bal then vág.őse.bal=fiaelse vág.őse.jobb=fiaif csúcs<>vág then csúcs.tartalom=vág.tartalom
Mit is vágunk ki? Aminek 1 gyereke van
vagy 1 sincsHa nem a megelőzőjét vágjuk, akkor kivágás
átnyilazással
Ha a megelőzőjét vágtuk ki, akkor a
tartalom átmásolása
Keresőfák egyenlő kulcsokkal• A Beszúr eljárás módosítása: a fa tulajdonságot <= kell
módosítani…• 1. stratégia: minden elemhez vegyünk fel egy láncolt listát
az egyenlő kulcsú elemek tárolására.• 2. stratégia: az új, megegyező kulcsú elemet hol a bal, hol a
jobb részfában tároljuk váltakozva• 3. stratégia: a bal és jobb részfát véletlenszerűen váltogatjuk• (a balfa legjobboldalsó/legnagyobb elemeit, ill. a jobbfa
legbaloldalsó/legkisebb elemeit építjük láncszerűen tovább)
Előd
Géza
Csenge
Csilla
Csaba
Árpád
Álmos
Előd
Előd
Előd Fajsz
Később érkező elem
Lánc kialakulása
Radix fák (kódfák)• Def: a jelsorozat lexikografikusan kisebb b-nél, ha
1, a első b-étől különböző eleme kisebb. 2. Ha a előtagja b-nek. (abc szerinti rendezés)
• A jelsorozatok tárolása nem szükséges
1001
0011
0 1
0 1
00
001
Véletlen építésű keresőfák• Adott kulcskészlethez többféle keresőfa is
felépíthető (a beszúrás sorrendjétől függően).• Def: Építsünk keresőfát n db. elemből. Ha
mindegyik sorrend (permutáció) egyformán vlsz, akkor véletlen építésű keresőfáról beszélünk.
• Def: Kiegyenlített a fa, ha a levelek magassága közel megegyező
• Tétel: Egy n különböző kulcsot tartalmazó véletlen építésű keresőfa átlagos magassága O(lg(n))
• Biz nélkül…vagyis a kiegyenlített fák létrejötte sokkal vlszbb,
mint különböző degenerációiké (pl. láncoké)
Faműveletek: forgatás• A forgatási műveletek megőrzik a fatulajdonságot• Használatuk: pl. fakiegyensúlyozáskor• JobbraForgat():Faújfa=balfabalfa=balfa.jobbfaújfa.jobbfa=Mereturn újfa
y
x a
bc
y
x
ab
c
Forgatás jobbra
Forgatás balra
Faműveletek: dupla forgatás• Jobbra2Forgat():Faújfa=balfa.jobbfaújfa.balfa.jobbfa=balfa.jobbfa.balfabalfa=balfa.jobbfa.jobbfaújfa.jobbfa=balfareturn újfa
x
z
dca
Forgatás jobbra
Forgatás balra
y
z
d
cb
x
a
y
b
Piros-fekete fák• Beszúrás, ill. törléskor a fa elveszítheti az
egyensúlyát.
• A piros-fekete fák: az egyensúly megtartását biztosítják. +1 bit információ (szín)a legrövidebb és leghosszabb út legfeljebb 2-szeres arányú lehet
• Fatulajdonságok:- minden csúcs vagy fekete, vagy piros- minden levél fekete- minden piros csúcs mindkét utódja fekete- bármely két azonos csúcsból a levélig jutó útban ugyanannyi fekete csúcs van
Fibonacci számok
• A következő sorozat: F0=0, F1=1, Fk+1+ Fk = Fk+2 .
• Pl. 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233,…
• Aranymetszés: =(1+sqr(5))/2=1.61803
• Konjugáltja: ’=(1-sqr(5))/2 = -0.6183
• Tétel: Fi=(i-’i )/sqr(5)
a Fibonacci számok exponenciálisan nőnek.
AVL fák (Adelson-Velskij-Landis)• Def: AVL-tulajdonság: Egy fa AVL fa, ha minden x
csúcsára |h(x.bal)-h(x.jobb)|<=1• Mennyi a a k magasságú AVL fák csomópontjainak
minimális száma (Gk)? G1=1, G2=2, G3=4, G4=7,… k>=3 esetén: Gk=1+Gk-1+Gk-2
• Tétel: Gk= Fk+2+1, ha k>=1
• Biz: 0,1-re nyilvánvaló. k>2-re indukcióval:
• Gk=1+Gk-1+Gk-2=1+Fk-1-1+Fk-2-1
• Következmény: egy n csomópontú AVL-fa k magassága nem nagyobb, mint O(log n). k<=1.44*log(n+1).
• Biz: n>=Fk-2-1 Fibonacci becslésből: n+1>=k k<=log(n+1) k<=1.44*log(n+1)
AVL kiegyensúlyozó algoritmus• Tétel: Ha S egy n csúcsú AVL fa, akkor a Beszúr
művelet után legfeljebb egy forgatással helyreállítható az AVL tulajdonság a beszúrás költsége ezután is O(log n) marad.
• Miért? Minden csúcsban tároljuk az itt gyökerező részfa magasságát. Beszúrás után az új elemhez vivő út bejárásával megkapjuk az első olyan elemet, ahol az AVL tulajdonság először megsérülitt végzünk forgatást
• Tétel: Ha S egy n csúcsú AVL fa, akkor a Töröl művelet után legfeljebb 1.44*log(n) forgatással helyreállítható az AVL tulajdonság
• Biz nélkül…
• (Hasonlít az edényrendezéshez)• Műveletek: Keres, Töröl, Beszúr• Legrosszabb eset: Θ(n), de átlagban Θ(1) is elérhető• Legegyszerűbb modell: legrosszabb eset: Θ(1)• Tfh. a lehetséges kulcsok egy véges egészintervallumból valók, vagyis min<=kulcs<=max.• Index-tábla felvétele• Keres(k) return(Index(k))
• Beszúr(x) Index(kulcs(x))=x
• Töröl(x) Index(kulcs(x))=NIL
Hasító (hash) táblázatok
0| 2| 3| 6| 8| 9|Index/Cím-tábla
Tábla rései
Index megismétlése nem
szükségesRekord tartalma
Hash táblázatok nagy kulcstérben• A teljes kulcstér (U) nagy (az indextábla nem
ábrázolható)• de az aktuálisan használt tér (K) kicsi (is lehet) UK indextábla leképezés• A K tér pontos mérete csak futásidőben derül kiUT hash tábla közötti leképező hash függvény
T=h(U). Elnevezés: h(k) a k kulcs hash értéke• Probléma: h(U) nem feltétlenül egy-egyértelmű,
azaz előfordulhat, hogy h(k1)=h(k2) kulcsütközés• Milyen legyen a h hash függvény? Jól szórjon –
minél véletlenszerűbb -
Ütközésfeloldás láncolással• Alapötlet: az ütköző (ugyanazon címre leképeződő) elemeket láncolt
listába összefogjuk• Beszúr(x)hash=h(kulcs(x))if T(hash)<>NIL then T(hash).Beszúr(x)else T(hash)=LáncLista(x)
• Keres(x)hash=h(kulcs(x))if T(hash)=NIL then return NILelse return(T(hash).Keres(x))
• Töröl(x)hash=h(kulcs(x))if T(hash)<>NIL then T(hash).Törölif T(hash).Méret=0 then T(hash)=NIL
alma baba nemez zászló
alföld német
nő
Láncolásos hasító technika elemzése• Legrosszabb eset: egyetlen láncolt lista
• Kitöltöttségi arány (n/m), ahol n a tárolt elemek összes száma, m a hash-tábla hossza
• Tétel: láncolt hasító technika és egyenletes hash függvény esetén, az átlagos keresési idő: Θ(1+ ).
• Biz: az átlagos keresési idő az átlagos lista végigjárásával arányos (sikeres és sikertelen keresés)
• Következtetés: 1. Fix hash-tábla esetén, sok elemre lineáris Θ(n) 2. Ha a hash-tábla a tárolt elemekkel arányosan nő, ill. kevés a tárolt elem, akkor Θ(1)
Hasító függvények• Mikor jó a hasító függvény? Ha a láncok kb.
egyenletesen nőnek<=azaz a T(y) index egyenletes
• Mivel T(y)=T(h(U(x))), függ az U(x) kulcseloszlástól
• Milyen az U(x) eloszlása?- fordítóprogramok: egymáshoz közeli szimbólumok
• H eloszlása független legyen az adatok esetleges szabályszerűségeitől- pl. a kulcs maradéka egy prímszámra nézve
• Feltételezzük, hogy a kulcs egész (ha nem az, akkor leképezhető)
Hasító függvények• Osztásos módszer: h(k)=k mod m, ahol m a hash
tábla mérete• Szorzásos módszer h(k)=m*(k*A mod 1)), ahol
0<A<1 egy állandó, k*A*mod 1: kA törtrészképzésPl. tfh: k belefér egy gépi szóba, és m=2p. Ekkor k*(A*m) egy gépi szorzás2 szó, ez mod m az alsó p bit levágását jelenti. (Donald Knuth)
• Minden rögzített hasító függvényhez létezik „rossz” adat (csak 1 lánc jön létre, Θ(n) elérés) a tényleges függvényt adott függvényosztályból véletlenszerűen (és adatfüggetlenül) választjuk ki. „Univerzális hasítási technika”
Nyílt címzés• Nyílt címzésű a hash tábla, ha az adatok NEM
láncolt listában, hanem benn a táblában vannak tárolva. Ütközés esetén újabb és újabb pozíciókat próbálunk ki, amíg csak üresre nem bukkanunk
a tábla betelhetnincs mutató, nincs láncolt listaa kipróbálandó rések címét a hash függvény (a kipróbálási számtól is függően) adja megadott kulcshoz a hash függvény a T címtér egy permutációját adja meg (vagyis mindent kipróbál)
• Beszúr(kulcs) próba=0 repeat index=h(kulcs,próba) if hash[index]=NIL then hash[index]=k return else próba=próba+1 endif until próba=max error „hash tábla túlcsordulás”
• Keres(kulcs) próba=0 repeat index=h(kulcs,próba) if hash[index]=kulcs then return index; else próba=próba+1 until hash[index]=NIL or próba=hash.max return NIL
Törlés: NIL-re állítás… Mi lesz az utána következő elemekkel?
Lineáris kipróbálás• Ha van egy h:U[0,1,…m-1] hash függvényünk, akkor a
lineáris kipróbálás függvénye a következő lesz: h’(k,i)=(h(k)+i) mod m.
• Hátránya: teljes szakaszokat betöltha egy jól szóró hash függvény belecímez, esetleg igen sok kipróbálásra kerül sor
Négyzetes kipróbálás• Ha van egy h:U[0,1,…m-1] hash függvényünk, akkor a
négyzetes kipróbálás függvénye a következő lesz: h’(k,i)=(h(k)+c2*i2+c1*i) mod m.
• Hátrányai: 1. Ha a c1,c2 konstansokat rosszul választjuk, akkor nem címzi be a teljes táblát 2. Ugyanoda címző elemek esetében ugyanazt a sorozatot járjuk be
A nyílt címzéses hash technika elemzése• Kitöltöttségi arány (n/m), ahol n a tárolt elemek összes
száma, m a hash-tábla hossza <=1• Tétel: Sikertelen keresés várható próbaszáma legfeljebb:
1/(1-)• Tfh. A hasítás egyenletes, vagyis egy (h(k,0), h(k,1),…
h(k,m-1)) kipróbálási sorozat egyenletesen állítja elő a (0,1,…,m) sorozat permutációit.
• Legyen pi annak valószínűsége, hogy pontosan i próba talál foglalt rést. (0<=i<=n-1), i>n-re pi=0
• A próbák számának várhatóértéke: 1+i=0Σ∞i*pi
• Legyen qi annak valószínűsége, hogy legfeljebb i próba talál foglalt rést. (aztán jön a szabad)
•i=0Σ∞i*pi = i=0Σ∞qi (annak a vlsz, hogy pontosan 0;1;… próba talál rést, ugyanannyi, mint a vlsz., hogy legfeljebb 0;1;… próba talál rést
• Mennyi a qi-k értéke?• q1=n/m annak a vlsz., hogy az első próba foglalt
elemet talál• q2=n/m*(n-1)/(m-1)• qi=n/m*(n-1)/(m-1)*…*(n-i+1)/(m-i+1)<= i
• A próbák számának várhatóértéke: 1+i=0Σ∞i*pi=1+
i=0Σ∞qi <=1+1 +2 +3 +)• 1. Elem biztos, 2. Elem 3. Elem • Ha félig van kitöltve, akkor próbaszám=2 lépés• Ha 90%-ig van kitöltve, akkor próbaszám=10 lépésBeszúrás időigénye legfeljebb: )
A nyílt címzéses hash technika elemzése
• Kitöltöttségi arány (n/m), ahol n a tárolt elemek összes száma, m a hash-tábla hossza <=1
• Tétel: Ilyenkor a sikeres keresés várható próbaszáma: 1/ln(1/(1- ))
• Bizonyítás nélkül… (az előzőhöz hasonló, a keresés nem fut végig, átlagolni kell)
50% kitöltöttségre: 1,38790% kitöltöttségre: 2.559 a nyílt címzéses hash technika a keresés
optimálását a beszúrás lassulásán keresztül éri el…
A nyílt címzéses hash technika elemzése