Rekurzió 4. Szlávi Péter ELTE Informatika Szakmódszertani Csoport

Slides:



Advertisements
Hasonló előadás
FOL függvényjelekkel Zsebibaba anyja A 2 harmadik hatványa a oszlopában az első blokk Ezek is nevek, de nem in- konstansok Azért, mert összetettek Predikátum:
Advertisements

TÖMÖRÍTÉS. Fogalma A tömörítés egy olyan eljárás, amelynek segítségével egy fájlból egy kisebb fájl állítható elő. A tömörítési arány függ a fájl típusától,
Forrás: Reiter István C_Sharp programozás lépésről lépésre (frissített tartalommal )
Gazdasági informatika - bevezető
Fájlkezelés.
Operációs rendszerek.
Muraközy Balázs: Mely vállalatok válnak gazellává?
Alhálózat számítás Osztályok Kezdő Kezdete Vége Alapértelmezett CIDR bitek alhálózati maszk megfelelője A /8 B
Becslés gyakorlat november 3.
Értékpapír-piaci egyenes
Program utasítássorozat

videós team Team vezetője: Tariné Péter Judit Tagok:
Lineáris függvények.
Kockázat és megbízhatóság
Mesterséges intelligencia
T.R. Adatbázis-kezelés - Alapfogalmak Adatbázis:
A Hazug paradoxona Minden krétai hazudik. (Mondta egy krétai.)
Downstream Power Back Off (DPBO)
Becsléselmélet - Konzultáció
Vörös-Gubicza Zsanett képzési referens MKIK
Algoritmusok és Adatszerkezetek I.
Rendszerező összefoglalás
Hipotézisvizsgálat.
VEREM.
Logikai programozás 2..
Nyelvek típusossága.
Adatbázis-kezelés (PL/SQL)
FÜGGVÉNYEK Legyen adott A és B két nem üres (szám)halmaz. Az A halmaz minden eleméhez rendeljük hozzá a B halmaz pontosan egy elemét. Ezt az egyértelmű.
Algebrai specifikációk
INFOÉRA 2006 Véletlenszámok
2. Bevezetés A programozásba
Az élesség beállítása vagy fókuszálás
VB ADATTÍPUSOK.
Szerkezetek Dinamikája
Downstream Power Back Off (DPBO)
Közigazgatási alapvizsga a Probono rendszerben
Business Mathematics
Grosz imre f. doc. Kombinációs hálózatok /43 kép
Algoritmusok és Adatszerkezetek I.
Regressziós modellek Regressziószámítás.
Algoritmusok és Adatszerkezetek I.
Algoritmusok és Adatszerkezetek I.
Számítógépes Hálózatok
Teljes visszalépéses elemzés
Készítette: Sinkovics Ferenc
AVL fák.
Aritmetikai kifejezések lengyelformára hozása
Informatikai gyakorlatok 11. évfolyam
Kifejezések kiértékelése * Lengyel-forma
Új pályainformációs eszközök - filmek
Bináris kereső fák Definíció: A bináris kereső fa egy bináris fa,
A Lineáris Keresés Buktatói
Matematikai Analízis elemei
SZAKKÉPZÉSI ÖNÉRTÉKELÉSI MODELL I. HELYZETFELMÉRŐ SZINT FOLYAMATA 8
További rendező és kereső algoritmusok
A szállítási probléma.
Valós számok Def. Egy algebrai struktúra rendezett test, ha test és rendezett integritási tartomány. Def. Egy (T; +,  ;  ) rendezett test felső határ.
Fák, bináris fák INFOÉRA Ez így 60 perc.
Matematika II. 5. előadás Geodézia szakmérnöki szak 2015/2016. tanév
Műveletek, függvények és tulajdonságaik Mátrix struktúrák:
Mintaillesztés Knuth-Morris-Pratt (KMP) algoritmus
Szöveges adatok tárolása
JAVA programozási nyelv NetBeans fejlesztőkörnyezetben I/13. évfolyam
Bevezetés Tematika Számonkérés Irodalom
A geometriai transzformációk
Mesterséges intelligencia
Algoritmusok.
Hagyományos megjelenítés
A T-spline felületreprezentáció
Előadás másolata:

Rekurzió 4. Szlávi Péter ELTE Informatika Szakmódszertani Csoport 2018.12.26. Rekurzió 4. Szlávi Péter ELTE Informatika Szakmódszertani Csoport szlavi@ludens.elte.hu http://izzo.inf.elte.hu/~szlavi 2000 Rekurzió 1

Tartalom 0 Bevezetés 1 Rekurzív specifikáció 2018.12.26. Tartalom 0 Bevezetés 0.1 A rekurzió lényege; „klasszikus” példák 0.2 A rekurzió helye a programkészítés folyamatában 1 Rekurzív specifikáció 1.1 Formalizmus 1.2 Példák 2 Rekurzív specifikáció és rekurzív algoritmus 3 Rekurzió megvalósítása nem rekurzív környezetben 3.1 Problémák 3.2 Példák 3.3 A valódi megoldás ötlete, avagy mit tesz egy fordító program? 2018.12.26. Rekurzió 4 Rekurzió 1

Tartalom 4 Rekurzió és iteráció 5 Rekurzív típusok 4.1 Oda 4.2 Vissza 2018.12.26. Tartalom 4 Rekurzió és iteráció 4.1 Oda 4.2 Vissza 5 Rekurzív típusok 5.1 Nevezetes rekurzív adatszerkezetek 5.2 Rekurzív adatszerkezetek megadása 5.3 A struktúrabejárás mint a feldolgozás „kerete” 2018.12.26. Rekurzió 4 Rekurzió 1

Tartalom 6 Rekurzív adattípusok: fák 6.1 Bináris fák 2018.12.26. Tartalom 6 Rekurzív adattípusok: fák 6.1 Bináris fák 6.1.0 Példák, alapfogalmak 6.1.1 Algebrai specifikáció 6.1.2 Exportmodul 6.1.3 Megvalósítási modul 6.1.4 Egy másik elképzelés 6.1.5 Összetett műveletek 6.1.6 Keresőfák 6.1.7 Rendező fák 6.2 Nem bináris fák 6.2.1 Algebrai specifikáció 6.2.2 Exportmodul 6.2.3 Megvalósítási modul 6.3 B-fák 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 6.1 Bináris fák 6.1.0 Példák, alapfogalmak Kifejezések Családfák Keresőfák (amik a gyors megtalálást célozzák) Rendezőfák („virtuális fa” -- időleges állapot) 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) 6.1.1 Algebrai specifikáció Típus BinFa(Elem): Asszociált műveletek: Üres:BinFa Üres?(BinFa):Logikai EgyEleműFa(Elem):BinFa [Létrehoz] BalraIlleszt(BinFa,BinFa):BinFa  {NemDef} [Illeszt] JobbraIlleszt(BinFa,BinFa):BinFa  {NemDef} GyökérElem(BinFa):Elem  {NemDef} [Elem] BalGyerek(BinFa):BinFa  {NemDef} [Rész] JobbGyerek(BinFa):BinFa  {NemDef} GyökérMódosít(BinFa,Elem):BinFa  {NemDef} [Módosít] *Illeszt(mire,mit) A rekord-szerű filozófia tükröződik a BinFa típuskonstrukció nyelvezetén. A „sokaságszerű” rekurzióból kimaradó műveletek: Leválaszt(Rek,Szel,Rek):RekRek  {NemDef} Elsőre(Rek):Rek  {NemDef} Következőre(Rek,Szel):Rek  {NemDef} Elején?(Rek):Logikai  {NemDef} Végén?(Rek):Logikai  {NemDef} 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) Jelölések: b,b’,b”,bb,b’:BinFa(Elem) – általában az aposztróf időbeliségre utal e:Elem „=”:BinFaBinFaLogikai, strukturális és elemérték-szintű azonosság Axiómák: 1º Üres – axióma Üres?(Üres) 1’º Üres – hiba-axióma b=Üres  GyökérElem(b)=NemDef  BalGyerek(b)=NemDef  JobbGyerek(b)=NemDef 2º EgyElemű – axióma b=EgyElemű(e)  Üres?(b)  GyökérElem(b)=e  Üres?(BalGyerek(b))  Üres?(JobbGyerek(b)) A szigorúbb feltételrendszerrel fogalmazódott meg az axiómarendszer. (Nem élünk az intelligensebb memóriakezelés adta nagyvonalúbb lehetőséggel.) 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) 3º *Illeszt – axióma [*=Bal/Jobb] Üres?(b)  Üres?(*Gyerek(b))  *raIlleszt(b,bb)=b’  *Gyerek(b’)=bb  GyökérElem(b)=GyökérElem(b’) … 3’º *Illeszt – hiba-axióma Üres?(b)  Üres?(*Gyerek(b))  *raIlleszt(b,bb)=NemDef 4º GyökérMódosít – axióma Üres?(b)  GyökérMódosít(b,e)=b’  GyökérElem(b’)=e 4’º GyökérMódosít – hiba-axióma Üres?(b)  GyökérMódosít(b,e)=NemDef 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) 6.1.2 Exportmodul ExportModul BinFa(Típus TElem): Függvény Üres?(Konstans f:BinFa):Logikai Konstans Üres:BinFa Függvény EgyEleműFa(Konstans e:TElem):BinFa Eljárás BalraIlleszt(Változó f:BinFa,Konstans g:BinFa) [Ef: az f nem üres, a balrésze üres] Eljárás JobbraIlleszt(Változó f:BinFa,Konstans g:BinFa) [Ef: az f nem üres, a jobbrésze üres] Függvény GyökérElem(Konstans f:BinFa):TElem [Ef: az f nem üres] Függvény BalGyerek(Konstans f:BinFa ):BinFa Függvény JobbGyerek(Konstans f:BinFa ):BinFa Eljárás GyökérMódosít(Változó f:BinFa,Konstans e:TElem) [Ef: az f nem üres] … 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) … Eljárás FaTörlés(Változó f:BinFa) [értékmegosztás esetén] Modul vége. Megjegyzés: A hiba-kezelése –szokásos módon– egy hiba-komponens- sel lehetséges. Ez esetben a fenti eljárások/függvények BinFa-paramé- terének hozzáférését változóra kell ókor-ókor módosítani. És szükség van egy Hibás? függvényre is. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) 6.1.3 Megvalósítási modul Megjegyzések: Visszavezetés az „általános” rekurzióra annak is a rekord-szemléletű definíciójára Modul BinFa(Típus TElem): Reprezentáció Típus RBinFa=Rekurzió(elem:TElem, bal,jobb:RBinFa) Változó f:RBinFa Implementáció Konstans Üres:RBinFa() Függvény Üres?(Konstans f:RBinFa):Logikai Üres?:=f=Üres Függvény vége. … átnevezés Átnevezés -- visszavezetés Visszavezetés a rekurzióra 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) … Függvény EgyEleműFa(Konstans e:TElem):RBinFa EgyEleműFa:=RBinFa(e,Üres,Üres) Függvény vége. Eljárás BalraIlleszt(Változó f:RBinFa, Konstans g:RBinFa) [Ef: RBinFa’Üres?(f)  RBinFa’Üres?(f.bal)] f.bal:=g Eljárás vége. Eljárás JobbraIlleszt(Változó f:RBinFa, Konstans g:RBinFa) [Ef: RBinFa’Üres?(f)  RBinFa’Üres?(f.jobb)] f.jobb:=g Eljárás vége. Függvény GyökérElem(Konstans f:RBinFa):RBinFa [Ef: RBinFa’Üres?(f)] GyökérElem:=f.elem Függvény vége. RBinFa-műveletekkel kifejezve Az operátorok explicit minősítése valójában fölösleges, hiszen paramétereinek típusa egyértelműen közli: RBinFa, azaz a reprezentációnál felhasznált típusról van szó. Csak a nyomaték kedvéért vezettem be az eddig nem használt jelölést. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) … Függvény BalGyerek(Konstans f:RBinFa):RBinFa BalGyerek:=f.bal Eljárás vége. Függvény JobbGyerek(Konstans f:RBinFa):RBinFa JobbGyerek:=f.jobb Eljárás vége. Eljárás GyökérMódosít(Változó f:RBinFa,Konstans e:TElem) [Ef: RBinFa’Üres?(f)] f.elem:=e Eljárás vége. Inicializálás [deklarációknál automatikusan végrehajtódik] f:=Üres Modul vége. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) 6.1.4 Egy másik elképzelés Alapja a rekurzió típus „tulajdonos-számlálásos” ábrázolási módszere. (Lásd előző előadásban.) Típus TBinFa=Rekord(gyökér:TBinFaElemMut, hiba:Logikai) TBinFaElemMut=TBinFaElem’Mutató TBinFaElem=Rekord(érték:TElem tulSzám:Egész [tulajdonosok száma] bal,jobb:TBinFa) 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) A műveletek értelmezésének módosítása: „intelligens”, azaz tulajdonos-számot kezelők: Eljárás ÜresséTesz(Változó bf:TBinFa) [Ef: bf] Függvény Üres?(Konstans bf:TBinFa):Logikai Függvény GyökérElem(Változó bf:TBinFa):TElem [Ef: bf] Eljárás GyökérElemMódosít(Változó bf:TBinFa, Konstans e:TElem) Függvény BalFa(Változó bf:TBinFa):TBinFa Függvény JobbFa(Változó bf:TBinFa):TBinFa Algoritmikus nyelvünk modulfogalma szerint az inicializáláskor üres értket kap. Így a bf ef. kezdetben is tud teljesülni. Általában a bf létezése nehezen ellenőrizhető feltétel. Érdemes belegondolni!!! Az algoritmikus nyelvünk modul fogalma szerint viszont az inicializálás (a deklarációhoz rendelt kód futása) során üres kezdőértéket kap. Kékkel jelöltük a tulajdonos-számtól független (tehát azt „triviálisan” kezelő) operációkat. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) „intelligensek” folytatása: Eljárás BalraIlleszt(Változó bf:TBinFa, Konstans mit:TBinFa) [Ef: bf  mit] Eljárás JobbraIlleszt(Változó bf:TBinFa, Konstans mit:TBinFa) [Ef: bf  mit] Eljárás ÉrtéketKap(Változó bf:TBinFa, Konstans mit:TBinFa) [Ef: bf,mit] Függvény Hibás?(Változó bf:TBinFa):Logikai [Ef: bf] 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) „erőszakos”, más szóval „bamba”, azaz tulajdono- sokra nem figyelők (az := operátoron túl): Eljárás Üres(Változó bf:TBinFa) [Ef: -] Eljárás EgyEleműFa(Változó bf:TBinFa, Konstans e:TELem) Eljárás _BalraIlleszt_(Változó bf:TBinFa, Konstans mit:TBinFa) [Ef: bf] Eljárás _JobbraIlleszt_(Változó bf:TBinFa, Konstans mit:TBinFa) Fontos különbséget tenni: konstruktor és konstrukciós műveletek között. Az utóbbi a bővebb művelethalmaz: ebbe tartozik minden művelet, amely az adott típusú szerkezetet módosítja. Az első kettő konstruktor művelet, tehát akkor működik helyesen, ha a bf nem létezik (de legalábbis üres). Az illesz- tők is csak akkor helyesek, ha a megfelelő ág üres. Hibajel- zés azonban semmiképpen nem képződik. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) … és az „alaphoz” tartozó, nem exportált tulajdo- nos-szám műveletek: Eljárás TulajNövelés( Változó bf:TBinFa): Változó sbf:TBinFa Ha nem Üres?(bf) akkor TBinFaElem(bf.gyoker).tulSzám:+1 sbf:=bf.BalFa TulajNövelés(sbf) bf._BalraIlleszt_(sbf) sbf:=bf.JobbFa TulajNövelés(sbf) bf._JobbraIlleszt_(sbf) Elágazás vége [nincs szükség az ÜresséTesz(sbf)-re, mert sbf nem vált tulajdonossá] Eljárás vége. Eljárás TulajCsökkentés( Változó bf:TBinFa): Változó sbf:TBinFa Ha nem Üres?(bf) akkor TBinFaElem(bf.gyoker).tulSzám:-1 sbf:=bf.BalFa TulajCsökkentés(sbf) bf._BalraIlleszt_(sbf) sbf:=bf.JobbFa TulajCsökkentés(sbf) bf._JobbraIlleszt_(sbf) Ha TBinFaElem(bf.gyökér).tulSzám=0 akkor Felszabadít(bf.gyökér) Elágazás vége [nincs szükség az ÜresséTesz(sbf)-re, mert sbf nem vált tulajdonossá] Eljárás vége. Az sbf konstrukciós műveletére explicite nincs szükség. Legalábbis az algoritmikus nyelvünkben. Nem így pl. a Delphi-Lazarus-ban, ahol nincs a deklaráció életbelépésekor automatikus inicializálás. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) Még egyszer a TBinFa-műveletkészlet használat- „módszertana”: mikor, melyik művelet használandó, módszertani elvek? Szabályok: Minden deklarált TBinFa adatobjektumot inicia- lizálni kell (Üres, EgyeleműFa konstruktorokkal). Az adat megsemmisülése előtt (pl. ez történik egy lokális adat eljárásból való kilépéskor) üressé kell tenni (ha adminisztratívan is tulajdonossá vált). Kerülendő a „sima” értékadás, helyette az Érté- ketKap-ot kell használni. Ha ez automatikusan nem történt meg. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) Illusztrálásképpen kövessük és értelmezzük a követ- kező programot: ! 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) 6.1.5 Összetett műveletek Elemszám: Mélység: … hf … Specifikáció – az uf. definíciós része Def: Elemszám:BinFaEgész  0 , ha Üres?(f) Elemszám(f):=  1+Elemszám(BalGyerek(f))+  Elemszám(JobbGyerek(f)) , ha egyébként Eljárás Elemszám(Konstans f:BinFa):Egész Ha Üres?(f) akkor Elemszám:=0 különben Elemszám:=1+Elemszám(BalGyerek(f))+ Elemszám(JobbGyerek(f)) Elágazás vége Eljárás vége. Algoritmus 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) Bejárások Eljárás BKJ(Konstans bf:BinFa): Ha nem Üres?(bf) akkor BKJ(BalGyerek(bf)) Ki: GyökérElem(bf) BKJ(JobbGyerek(bf)) Elágazás vége Eljárás vége. Eljárás KBJ(Konstans bf:BinFa): Ha nem Üres?(bf) akkor Ki: GyökérElem(bf) KBJ(BalGyerek(bf)) KBJ(JobbGyerek(bf)) Elágazás vége Eljárás vége. Eljárás BJK(Konstans bf:BinFa): Ha nem Üres?(bf) akkor BJK(BalGyerek(bf)) BJK(JobbGyerek(bf)) Ki: GyökérElem(bf) Elágazás vége Eljárás vége. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) A bejárások iteratív változatai Bal-közép-jobb Az algoritmus, először „kézzel”: * b + a 2 := x 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) A bejárások iteratív változatai Az algoritmus, vázlatosan: Még nem másodszor értünk vissza a gyökérhez … gyökérre állás Ciklus amíg nem le a gyökérről Ciklus amíg nem le a fáról Verembe(ahol tartunk) Balralépés Ciklus vége Veremből(ahova vissza kell lépni) Ha nem le a gyökérről akkor Ki: Elem(ahol tartunk) Jobbralépés Elágazás vége Ciklus vége … Nem léptünk le egy levélről, azaz van út előre * b + a 2 := x 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) Kövessük az algoritmust üres és egyelemű binfára! … és pontosítva: Eljárás BKJ(Konstans bf:BinFa): Változó rf:BinFa; v:Verem(BinFa) Üres(v); Verembe(v,Üres) rf:=bf Ciklus amíg nem Üres?(v) Ciklus amíg nem Üres?(rf) Verembe(v,rf) rf:=BalGyerek(rf) Ciklus vége Veremből(v,rf) Ha nem Üres?(v) akkor Ki:Gyökér(rf) rf:=JobbGyerek(rf) Elágazás vége Ciklus vége Eljárás vége. … gyökérre állás Ciklus amíg nem le a gyökérről Ciklus amíg nem le a fáról Verembe(ahol tartunk) Balralépés Ciklus vége Veremből(ahova vissza kell lépni) Ha nem le a gyökérről akkor Ki: Elem(ahol tartunk) Jobbralépés Elágazás vége Ciklus vége … 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) Közép-bal-jobb … hf … Bal-jobb-közép … hf … 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 6.1.6 Kereső fák Cél: gyors keresés + kényelmes módosíthatóság Lényeg: Típus TElem=Rekord(kulcs:TKulcs, egyéb:TEgyéb) Műveletek (a szokásos BinFa műveleteken túl): keresés elem-beillesztés, -törlés kiegyensúlyozás Rövid leírhatóság kedvéért, átnevezzük: TKFa Logaritmikus sebességgel Láncolt szerkezetek rugalmasságával Típus TKeresőFa=BinFa(TElem) [Ef: Rendezett(TKulcs) Típusinvariáns: f:TKeresőFa: GyökérElem(r).kulcs>GyökérElem(BalGyerek(r)).kulcs  GyökérElem(r).kulcsGyökérElem(JobbGyerek(r)).kulcs] A „keresőfa” tulajdonság 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Kulcsegyértelműség Rekord-szerűen: Függvény Keresés(Konstans k:TKulcs, kf:TKFa):TKFa [Uf: ekf: k=e.kulcs  f=Keresés(k,kf): GyökérElem(f).kulcs=k  ¬ekf: k=e.kulcs  Keresés(k,kf)=Üres] Függvény Beillesztés(Konstans e:TElem, kf:TKFa):TKFa [Ef: ║{xkf: x.kulcs=e.kulcs}║≤1 Uf: f=Beillesztés(e,kf)  akf: a.kulcs=e.kulcs  xkf: x.kulcse.kulcs  xf  xkf: x.kulcs=e.kulcs  x’=ef  ¬akf: a.kulcs=e.kulcs xkf  xf  ef ] Definíciós ok miatt: a rendezés szerinti helyére kerül az e elem! 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Kulcsegyértelműség Függvény Törlés(Konstans k:TKulcs, kf:TKFa):TKFa [Ef: x,ykf: xy  x.kulcsy.kulcs Uf: ekf: e.kulcs=k  f=Törlés(k,kf): ef  akf: a.kulcsk  af  ¬ekf: e.kulcs=k Törlés(k,kf)=kf] Függvény Kiegyensúlyozás(Konstans kf:TKFa):TKFa [Uf: Kiegyensúlyozott(kf)  Kiegyensúlyozás(kf)=kf  ¬Kiegyensúlyozott(kf)  f=Kiegyensúlyozás(kf): Kiegyensúlyozott(f)] L. később! 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Kimenő értéke a kf-nek Sokaság-szerűen: Előzetes megjegyzés: az utófeltételben a BinFa sokaság-szerű műveleteit függvé- nyes jelölésekkel (értelemszerű értéktípussal) fogjuk használni. Szavakkal: ha benne van a keresett, akkor az lesz az aktuális; ha nincs benne, akkor van olyan keresőfa, amely a kf-ből úgy kapható, hogy az aktuálisra illesztjük a megfelelő szelektoron át. (Azaz oda lesz állítva az akt mutató.) Eljárás Keresés(Konstans k:TKulcs, Változó kf:TKFa, van:Logikai, melyik:Szelektor) [Uf: ekf:k=e.kulcs  Elem(kf’).kulcs=k  van  ¬ekf:k=e.kulcs  ¬van  fTKFa: f=Illeszt(EgyEleműFa((k,eb)),kf’,melyik)] 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Eljárás Beillesztés(Konstans e:TElem, Változó kf:TKFa) [Ef: ║{xkf: x.kulcs=e.kulcs}║≤1 Uf: ekf’  Elem(kf’)=e] Eljárás Törlés(Konstans k:TKulcs, Változó kf:TKFa) [Ef: x,ykf: xy  x.kulcsy.kulcs Uf: ekf: e.kulcs=k  akf: af  ef  ¬ekf: e.kulcs=k  kf’=kf] Függvény Kiegyensúlyozás(Változó kf:TKFa) [… ugyanaz …] Kimenő értéke a kf-nek 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Megvalósítások: Keresés Rekord-szerűen: Függvény Keresés(Konstans k:TKulcs, kf:TKFa):TKFa [Uf: ekf: k=e.kulcs  f=Keresés(k,kf)  GyökérElem(f).kulcs=k  ¬ekf: k=e.kulcs  Keresés(k,kf)=Üres] Elágazás Üres?(kf) esetén Keresés:=kf k<GyökérElem(kf).kulcs esetén Keresés:= Keresés(k,BalGyerek(kf)) k>GyökérElem(kf).kulcs esetén Keresés:= Keresés(k,JobbGyerek(kf)) k=GyökérElem(kf).kulcs esetén Keresés:=kf Elágazás vége Függvény vége. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Sokaság-szerűen (visszatérünk a rekurzió nyelvére): Eljárás Keresés(Konstans k:TKulcs, Változó kf:TKFa,van:Logikai,melyik:Szelektor): [Uf: ekf: k=e.kulcs  Elem(kf’).kulcs=k  van  ¬ekf: k=e.kulcs  ¬van  Üres?(kf)  fTKFa: f=Illeszt(EgyEleműFa((k,eb)),kf’,melyik)] Ha nem Üres?(kf) akkor Elsőre(kf); van:=Igaz [értsd: lehet, hogy van] Ciklus amíg van és kElem(kf).kulcs Ha k<Elem(kf).kulcs akkor Ha Üres?(Rész(kf,bal)) akkor van:=Hamis; melyik:=bal különben Következőre(kf,bal) Elágazás vége különben … A sokaság-szerűség szinte „diktálja” az iteratív megoldást. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák … különben Ha Üres?(Rész(kf,jobb)) akkor van:=Hamis; melyik:=jobb különben Következőre(kf,jobb) Elágazás vége Elágazás vége Ciklus vége különben [Üres esetben] van:=Hamis Elágazás vége Eljárás vége. Ugyanezt Rekord-szerűen is: Függvény Keresés2(Konstans k:TKulcs, kf:TKFa, Változó melyik:Szelektor’):TKFa … hf.; vigyázat: a kf üres esetén melyik-nek különleges érték (pl. gyökér) kell; Szelektor-bővítés: Szelektor’… 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Törlés Az extra gond: a törlés során az elem kiesés miatt a fát sokszor át kell strukturálni, hogy a binfaság és a típusinvariancia is megmaradjon. Az ‘egyértelműség’ ef-ével nem foglalkozunk! Rekord-szerűen: A megoldandó estek: a törlendő levélelem nincs jobboldali részfája nincs baloldali részfája egyik részfája sem üres Függvény Törlés(Konstans k:TKulcs, kf:TKFa):TKFa [Uf: ekf: e.kulcs=k  f=Törlés(k,kf): …  ¬ekf: e.kulcs=k Törlés(k,kf)=kf]    elemzés  lásd a „nincs jobboldali …” esetet 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Függvény Törlés(Konstans k:TKulcs,kf:TKFa):TKFa [Uf: ekf: e.kulcs=k  f=Törlés(k,kf): …  ¬ekf: e.kulcs=k Törlés(k,kf)=kf] Elágazás Üres?(kf) esetén Törlés:=kf k<GyökérElem(kf).kulcs esetén Törlés:= TKFa(GyökérElem(kf), Törlés(k,BalGyerek(kf)), JobbGyerek(kf)) k>GyökérElem(kf).kulcs esetén Törlés:= TKFa(GyökérElem(kf), JobbGyerek(kf), Törlés(k,BalGyerek(kf)) k=GyökérElem(kf).kulcs esetén Törlés:= GyökérTörlés(k,kf) Elágazás vége Függvény vége. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Függvény GyökérTörlés(Konstans k:TKulcs, kf:TKFa):TKFa Változó fa:TKFa; jlb:TElem Elágazás Üres?(BalGyerek(kf)) esetén GyökérTörlés:=JobbGyerek(kf) Üres?(JobbGyerek(kf)) esetén GyökérTörlés:=BalGyerek(kf) egyéb esetben JobbLegbalLe(kf,jlb,fa) GyökérTörlés:=TKFa(jlb, BalGyerek(kf), fa) Elágazás vége Függvény vége. Eljárás JobbLegbalLe(Konstans kf:TKFa, Változó e:TElem, ág:TKFa): … hf. … JobbGyerek(kf)-jlb=fa 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Sokaság-szerűen: Az ábrázolás további gondja: nem elegendő a törlendőre pozícionálni, hanem annak őse is kell, hiszen őrá kell akasztani a törölt leszárma- zottait. Lásd az alábbi magyarázó ábrát: 9 ős 9 9 4 törlendő 6 1 6 1 1 7 1 7 7 6 8 8 6 8 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Algoritmusa: Eljárás Törlés(Konstans k:TKulcs, Változó kf:TKFa): Változó melyik:Szelektor talált:Logikai MódosítottKeresés(k,kf,melyik,talált) Ha talált akkor TénylegesTörlés(melyik,kf) Eljárás vége. Eljárás MódosítottKeresés(Konstans k:TKulcs, Változó kf:TKFa,melyik:Szelektor,talált:Logikai): [Uf: Elem(Rész(kf’,melyik)).kulcs=k] … hf. … Eljárás vége. Eljárás TénylegesTörlés(Konstans melyik:Szelektor, Változó kf:TKFa): … hf. … Eljárás vége. A MódosítottKeresés precizírozandó: Uf: Elején?(kf)  Elem(kf).kulcs=k  Elem(kf’).kulcs=k  melyik=gyökér (Szelektor!)  … Azaz az akt melyik szelektorán lóg a törlendő k kulcsú 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 1 2 2 1 3 Kiegyensúlyozás A probléma forrása… Definíciók: 1. Kiegyensúlyozott az a bináris fa, amelynek tetszőleges pont- jában „gyökerező” részfáinak ághosszai legfeljebb eggyel térnek el egymástól (AVL-fa). 2. Teljesen kiegyensúlyozott az a bináris fa, amelynek tetszőleges pontjában „gyökerező” részfáinak pontszámai legfeljebb eggyel térnek el egymástól. 3. Teljes az a bináris fa, amelynek tetszőleges pontjában „gyöke- rező” részfáinak pontszámai pontosan megegyeznek. Állítás: {kf: Teljes(kf)}  {kf: TeljesenKiegyensúlyozott(kf)}   {kf: Kiegyensúlyozott(kf)} Praktikus megállapodás: csak AVL-fákkal foglalkozunk. 3 ((1)2(3)) és (1(2(3))) „lényegében” ugyanazt a keresőfát jelöli, de mégis mennyire más Kérdés: bármely fát át lehet-e alakítani (akár rendezettségtől függetlenül) teljessé, vagy teljesen kiegyensúlyozottá, vagy kiegyensúlyozottá? Állítás: nem lehet tetszőleges fát teljessé tenni, de teljesen kiegyensúlyozottá vagy kiegyensúlyozottá igen. Ui.: * teljes bináris fa elemeinek a száma: 1 v. 3 v. … 2n-1; az ettől eltérő elemszámú fát nem lehet teljessé tenni… * teljesen kiegyensúlyozott (elemi) fák: 1..5 eleműek; érzés: bármely n>5 elemű fát átalakíthatunk úgy, hogy a két részfa elemszáma legfeljebb 1-gyel térjen el a másiktól: n=1+(n div 2)+(n-(n div 2)-1), ahol 0<=(n div 2)-(n-(n div 2)-1)<=1 indukcióval belátható… * kiegyensúlyozottra hasonlóan… 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák A cél: a beszúrás és a törlés műveletek módosítása úgy, hogy ha előtte az AVL-tulajdonság teljesült, akkor utána is teljesüljön. A beszúrás lényege: a) egyszeres elforgatás x y y x f1 f3 f1 f2 ? új elem f2 f3 ? új elem 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák b) kétszeres elforgatás Technikai megjegyzés: a folyamatos kiegyensúlyozás megkönnyíthető a szintszám tárolásával: Típus TElem=Rekord(kulcs:TKulcs,egyéb:TEgyéb, szint:Egész) x z y y x z f4 f1 f2 f3 f2 f3 f1 f4 ? új elem ? új elem 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 6.1.7 Rendező fák Cél: a rendezés hatékony támogatása. Kiindulópont: keresőfa, amelyet Bal-közép-jobb bejárva kapjuk a rendezett sorozatot. (Felépítéskor kiegyensúlyo- zottságra kell törekedni.) Ábrázolási szokások: Kitaposott úttal  dinamikus fa (módosítható) Kupaccal (heap-pel)  statikus A keresőfa-tulajdonságot helyettesítve a kupac-tulajdonsággal 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Kitaposott út: Sokaság-szemléletű, ui.: Minden elemnek van egy „visszamutató” mezője, a bejárás (most a BKJ) szerint kitöltve: Típus TBinFaElem=Rekord( elem:TElem, bal,jobb,vissza:TBinFaElem’Mutató)  nem rekurzív struktúra (így nincs Rekord-szerű változata!) lehetővé teszi a Veremnélküli használatot 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Az exportmodul és Függvény VisszaŐs(Konstans rf:BinFa):BinFa [Uf: az akt az eddigi akt őse lesz, ha lehet, különben nemDef] Eljárás VisszaMódosít(Változó rf:BinFa, Konstans mire:BinFa) [Uf: az rf akt elemének vissza mutatója a mire akt elemére mutasson] a megvalósítás is módosul… Függvény VisszaŐs(Konstans rf:BinFa):BinFa … hf. … Eljárás VisszaMódosít(Változó rf:BinFa, Konstans mire:BinFa) … hf. … … a többi rutin is módosítandó … 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák egy új alap elv a műveletekhez: minden művelet az aktuális elemhez képest értendő Pl. egy ága akkor Üres, ha az aktuális elem adott ága üres; vagy BalGyerek függvény hívása a paraméterfát eredményezi, de a fa aktuális eleme bal „irányba” lép egyet… 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Egy elem beillesztése: Eljárás Beilleszt(Változó rf:BinFa, Konstans e:TElem): [Uf: … hf. … ] Változó sf,új,előző:BinFa, irány:Szelektor új:=EgyeleműFa(e) sf:=rf Ciklus amíg nem Üres?(sf) előző:=sf Ha e<GyökérElem(előző) akkor sf:=BalGyerek(sf); irány:=bal különben sf:=JobbGyerek(sf); irány:=jobb Elágazás vége Ciklus vége … előző gyökér|akt … Elem bal|jobb|vissza Elem bal|jobb|vissza új gyökér|akt 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák előző gyökér|akt … Ha irány=bal akkor BalraIlleszt(előző,új) VisszaMódosít(új,előző) különben JobbraIlleszt(előző,új) VisszaMódosít(új,VisszaŐs(előző)) VisszaMódosít(előző,Üres) Elágazás vége Eljárás vége. … Elem bal|jobb|vissza Elem bal|jobb|vissza Elem bal|jobb|vissza Elem bal|jobb|vissza új gyökér|akt Egy elem törlése: … hf. … Elem bal|jobb|vissza új gyökér|akt 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Maga a rendezett sorozat: (=BKJ-bejárással) Eljárás BKJ(Konstans f: BinFa): Változó sf:BinFa sf:=f Ciklus amíg nem Üres?(sf) Ciklus amíg nem Üres?(BalGyerek(sf)) sf:=BalGyerek(sf) Ciklus vége Ki: GyökérElem(sf) Ciklus amíg Üres?(JobbGyerek(sf)) és nem Üres?(VisszaŐs(sf)) sf:=VisszaŐs(sf) sf:=JobbGyerek(sf) Eljárás vége. 5 3 7 2 4 6 8 1 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Kupaccal (heap/halom/piramis): Folytonos ábrázolású Speciális kupac-tulajdonság: a kupac gyökéreleme kisebb (vagy egyenlő), mint a közvetlen leszármazottak a kupac balról folytonos, azaz ha nem teljes a fa, akkor csak a legutolsó szintből hiányozhatnak elemek, de azok is csak a szint jobb széléről. 5 5 3 7 2 4 6 8 1 3 7 2 4 6 8 1 BalGyerek(i)=2*i JobbGyerek(i)=2*i+1 5 3 7 2 4 6 8 1 1 2 3 4 5 6 7 8 A rendezés „irányától” függően 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 5 3 7 2 4 6 8 1 1 2 3 4 5 6 7 8 A rendezendő sorozat A kupac-rendezés „működése” (példa): 5 3 7 2 4 6 8 1 A kupacosítás: 5 3 7 2 4 6 8 1 5 3 7 1 4 6 8 2 5 3 6 1 4 7 8 2 5 1 6 3 4 7 8 2 5 1 6 2 4 7 8 3 1 5 6 2 4 7 8 3 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Ime a kupac! 1 2 6 5 4 7 8 3 1 2 6 3 4 7 8 5 A rendezés: „Helyre-csere”! 8 1 2 6 3 4 7 5 Kupac helyrehozás 5 2 6 3 4 7 8 1 2 5 6 3 4 7 8 1 2 3 6 5 4 7 8 1 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák „Helyre-csere”! 2 3 6 5 4 7 8 1 „Helyre-csere”! Kupac helyrehozás 8 3 6 5 4 7 2 1 3 8 6 5 4 7 2 1 3 4 6 5 8 7 2 1 Kupac helyrehozás 7 4 6 5 8 3 2 1 4 7 6 5 8 3 2 1 4 5 6 7 8 3 2 1 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák „Helyre-csere”! 4 5 6 7 8 3 2 1 „Helyre-csere”! Kupac helyrehozás 8 5 6 7 4 3 2 1 5 8 6 7 4 3 2 1 5 7 6 8 4 3 2 1 Kupac helyrehozás „Helyre-csere”! 8 7 6 5 4 3 2 1 6 7 8 5 4 3 2 1 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Kupac helyrehozás 8 7 6 5 4 3 2 1 „Helyre-csere”! 7 8 6 5 4 3 2 1 8 7 6 5 4 3 2 1 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 A rendezett sorozat 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák A kupac fogalomkörének megközelítése: Kupac= BinFa=Tömb(1..ElemSzám: TElem) típusú vektor, KupacHossz = a kupac (azaz a még rendezetlen elemek) elemszáma, BalGyerek(elemindex) = 2*elemindex, JobbGyerek(elemindex) = 2*elemindex+1, UtolsóSzülő(kupac) = kupachossz DIV 2 MinGyerek(elemindex) = a kisebbik gyereke az elemnek, VanGyerek(elemindex) = igaz, ha BalGyerek(elemindex)£KupacHossz, Érték(elemindex) = az elem fabeli értéke. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Algoritmusvázlatok: Eljárás HeapSort(Változó kupac:BinFa): HSFaLétrehozása(kupac) Ciklus i=KupacHossz-tól 2-ig -1-esével Csere(i,1) [KupacHosszi] KupacHossz:-1 GyökérHelyre(1) Ciklus vége Eljárás vége. a minimumot a rendezettek közé a csere miatt elromlott „fa" kupacosítása Eljárás HSFalétrehozása(Változó kupac:BinFa): Ciklus j=UtolsóSzülő(kupac)-től 1-ig -1-esével GyökérHelyre(j) Ciklus vége Eljárás vége. a j. elem „lecsúsztatása" a kupac-hosszadik elemig bezárólag 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Eljárás GyökérHelyre(Változó gyökér: Egész): szülő:=gyökér; gyerek:=MinGyerek(szülő) Ciklus amíg VanGyerek(szülő) és Érték(szülő)>Érték(gyerek) Csere(szülő,gyerek); szülő:=gyerek gyerek:=MinGyerek(gyerek) Ciklus vége Eljárás vége. Függvény MinGyerek(Konstans elem:Egész):Egész Elágazás JobbGyerek(elem)>KupacHossz esetén Mingyerek:=BalGyerek(elem) Érték(BalGyerek(elem))<Érték(JobbGyerek(elem)) esetén Mingyerek:=BalGyerek(elem) egyéb esetben Mingyerek:=JobbGyerek(elem) Elágazás vége Függvény vége. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák Függvény MinGyerek(Konstans elem:Egész):Egész Elágazás JobbGyerek(elem)>KupacHossz esetén Mingyerek:=BalGyerek(elem) Érték(BalGyerek(elem))<Érték(JobbGyerek(elem)) esetén Mingyerek:=BalGyerek(elem) egyéb esetben Mingyerek:=JobbGyerek(elem) Elágazás vége Függvény vége. 2018.12.26. 6 Rekurzív adattípusok: fák A heapsort hatékonyságáról (T; N=elemszám) HeapSort (HS) T(HS)=T(HSFL)+T(N*(…+GyH))= =O(N)+O(NlogN)=O(NlogN) HSFaLétrehozása (HSFL) T(HSFL)=T((N Div 2)*GyH)= =O(N*logN) (sőt bizonyítható: O(N)) GyökérHelyre (GyH) T(GyH)=T(logN*(…+MGy))= =O(logN) MinGyerek (MGy) T(MGy)=O(1) A heapsort hatékonyságáról (T; N=elemszám) HeapSort (HS) T(HS)=T(HSFL)+T(N*(…+GyH))= = HSFaLétrehozása (HSFL) T(HSFL)=T((N Div 2)*GyH)= =O(N*logN) (sőt bizonyítható: O(N)) GyökérHelyre (GyH) T(GyH)=T(logN*(…+MGy))= =O(logN) MinGyerek (MGy) T(MGy)=O(1) Eljárás GyökérHelyre(Változó gyökér:Egész): szülő:=gyökér; gyerek:=MinGyerek(szülő) Ciklus amíg VanGyerek(szülő) és Érték(szülő)>Érték(gyerek) Csere(szülő,gyerek); szülő:=gyerek gyerek:=MinGyerek(gyerek) Ciklus vége Eljárás vége. Eljárás HeapSort(Változó kupac:BinFa): HSFaLétrehozása(kupac) Ciklus i=KupacHossz-tól 2-ig -1-esével Csere(i,1); KupacHossz:-1 GyökérHelyre(1) Ciklus vége Eljárás vége. Eljárás HSFalétrehozása(Változó kupac:BinFa): Ciklus j=UtolsóSzülő(kupac)-től 1-ig -1-esével GyökérHelyre(j) Ciklus vége Eljárás vége. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák Egy lehetséges Pascal megvalósítás kezdeményei: Type TKupac=Record kH:Integer; elem:Array [1..MaxN] of TElem End; {Exportálandó műveletek:} Procedure KupacLetrehozas(Var kupac:TKupac); Function KupacHossz(Const kupac:TKupac):Integer; Function Balgyerek(Const kupac:TKupac; Const kinek:Integer):Integer; Function Jobbgyerek(Const kupac:TKupac; Const kinek:Integer):Integer; Function Mingyerek(Const kupac:TKupac; Const kinek:Integer):Integer; Function Vangyerek(Const kupac:TKupac; Const kinek:Integer):Boolean; Function UtolsoSzulo(Const kupac:TKupac):Integer; Function Ertek(Const kupac:TKupac; Const kinek:Integer):TElem; Procedure KupacRovidites(Var kupac:TKupac); Procedure GyokerHelyre(Var kupac:TKupac; Const gyoker:Integer); Procedure Csere(Var kupac:TKupac; Const mit,mivel:Integer); 2018.12.26. Rekurzió 4

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák A kupac speciális alkalmazása: prioritási sor Prioritási sor = kupac + kupachossz Eljárás PrSorba(Változó PS:BinFa, Konstans elem:TElem): PS.kupac(PS.hossz+1):=elem PS.hossz:=PS.hossz+1 gyerek:=PS.hossz; szülő:=gyerek DIV 2 Ciklus amíg szülő1 és PS.kupac(gyerek)>PS.kupac(szülő) Csere(PS.kupac(gyerek),PS.kupac(szülő)) gyerek:=szülő; szülő:=gyerek DIV 2 Ciklus vége Eljárás vége. Eljárás PrSorból(Változó PS:BinFa, elem:TElem): … hf. … Eljárás vége. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák A Kupac mint típus Algebrai leírása Típus Kupac(Elem): Asszociált műveletek: Létrehoz(Elem*): Kupac [egy elemsorozatból készít kupacot] Kupac?(Kupac,Egész): Logikai [rendelkezik-e a kupac- tulajdonsággal a struktúra egy adott indexű elemétől kezdődően] KupacHossz(Kupac): Egész [az elemsorozat kupac-tulajdonsággal rendelkező „elejének” hossza] Méret(KupacTömb): Egész [a teljes elemsorozat hossza] KupacRedukció(Kupac): Kupac [a Kupac első és utolsó elemének cseréje, majd a kupac-tulajdonság helyreállítása] Elem(KupacTömb,Egész): Elem{NemDef} [az elemsorozat adottadik eleme] BalGyerek(Egész): Egész JobbGyerek(Egész): Egész 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Axiómák: Jelölések: s,s’:Kupac(Elem) = Kupac-típusú objektum t:Tömb(Elem) = tömb típusú objektum 1o Létrehoz – axióma s=Létrehoz(t)  Kupac?( s,1)  KupacHossz(s)=Méret(s)=Méret(t) 2o Kupac? – axióma Kupac?(s,i)  i>KupacHossz(s)  BalGyerek(i)KupacHossz(s)  Elem(s,i)Elem(s,BalGyerek(i))  Kupac?(s,BalGyerek(i))  JobbGyerek(i)KupacHossz(s)  Elem(s,i)Elem(s,JobbGyerek(i))  Kupac?(s,JobblGyerek(i)) 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 3o KupacRedukció – axióma s’=KupacRedukció(s)  Elem(s,1)=Elem(s’,KupacHossz(s))  KupacHossz(s’)=KupacHossz(s)-1  Kupac?(s’,1) 4o Elem – hiba-axióma i[1..Méret(s)]  Elem(s,i)=NemDef 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 6.2 Nem bináris fák 6.2.1 Algebrai specifikáció Típus Fa(Elem): Asszociált műveletek: Üres:Fa Üres?(Fa):Logikai EgyEleműFa(Elem):Fa [Létrehoz] GyerekSzám(Fa):Egész Beilleszt(Fa,Fa):Fa  {NemDef} [Illeszt utolsó gyerekként] GyökérElem(Fa):Elem  {NemDef} [Elem] Gyerek(Fa,Egész):Fa  {NemDef} [Rész; i. gyermek] GyökérMódosít(Fa,Elem):Fa  {NemDef} [Módosít] Beilleszt(mire,mit) 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) Jelölések: f,f’,ff,f’:Fa(Elem) – általában az aposztróf időbeliségre utal e:Elem i:Egész „=”:FaFaLogikai, strukturális és elemérték-szintű azonosság Axiómák: 1º Üres – axióma Üres?(Üres) 1’º Üres – hiba-axióma GyökérElem(Üres)=NemDef  GyerekSzám(Üres)=0  Gyerek(Üres,i)=NemDef 2º EgyEleműFa – axióma f=EgyEleműFa(e)  Üres?(f)  GyökérElem(f)=e  GyerekSzám(f)=0  Üres?(Gyerek(f,i)) 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák (folytatás) 2018.12.26. 6 Rekurzív adattípusok: fák (folytatás) 3º Beilleszt – axióma Üres?(f)  GyerekSzám(f)=i  Beilleszt(f,ff)=f’  Gyerek(f’,i+1)=ff  GyerekSzám(f’)=i+1  j>i  Üres?(Gyerek(f,j)) 3’º Beilleszt – hiba-axióma Üres?(f)  Beilleszt(f,ff)=NemDef 4º GyökérMódosít – axióma Üres?(f)  GyökérMódosít(f,e)=f’  GyökérElem(f’)=e 5’º GyökérMódosít – hiba-axióma Üres?(f)  GyökérMódosít(f,e)=NemDef 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 6.2.2 Exportmodul ExportModul Fa(Típus TElem): Függvény Üres?(Konstans f:Fa):Logikai Konstans Üres:Fa Függvény EgyEleműFa(Konstans e:TElem):Fa Függvény GyerekSzám(Konstans f:Fa):Egész Eljárás Beilleszt(Változó mire:Fa, Konstans mit:Fa) [Ef: mire nem üres Uf: … utolsó gyerekként …] Függvény GyökérElem(Konstans f:Fa):TElem [Ef: f nem üres] Függvény Gyerek(Konstans f:Fa,i:Egész):Fa [Ef: f nem üres és az „i-edikség” értelmesen megfogalmazható] … 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák … Eljárás GyökérMódosít(Változó f:Fa, Konstans e:TElem) [Ef: f nem Üres] Modul vége. Megjegyzés: A hiba-kezelése –szokásos módon– egy hiba-komponens- sel lehetséges. Ez esetben a fenti eljárások/függvények Fa-paraméteré- nek hozzáférését változóra kell ókor-ókor módosítani. És szükség van egy Hibás? Függvényre is. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 6.2.3 Megvalósítási modul Rekord-szerű, visszavezetés a rekurzióra Modul Fa(Típus TElem): Reprezentáció Változó f:Rekurzió(Elem:TElem, ág:Sorozat(Fa)) Implementáció Függvény Üres?(Konstans f:Fa):Logikai … hf. … Konstans Üres:Fa … hf. … Függvény EgyEleműFa(Konstans e:TElem):Fa EgyEleműFa:=Fa(e,ÜresSorozat) Függvény vége. Függvény GyerekSzám(Konstans f:Fa):Egész GyerekSzám:=ElemSzám(f.ág) Függvény vége. … Sorozat-műveletek: ÜresSorozat, ElemSzám, Végére, (i) 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák … Eljárás Beilleszt(Változó mire:Fa, Konstans mit:Fa): mire.ág:=Végére(mire.ág,mit) Eljárás vége. Függvény GyökérElem(Konstans f:Fa):TElem … hf. … Eljárás Gyerek(Konstans f:Fa,i:Egész):Fa Ha iElemSzám(f) akkor Gyerek:=f.ág(i) különben Gyerek:=Üres Függvény vége. Eljárás GyökérMódosít(Változó f:Fa, Konstans e:TElem) … hf. … Modul vége. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Egy alternatív megvalósítás: bináris faként Modul Fa(Típus TElem): Reprezentáció Változó f:BinFa(TElem) Implementáció Függvény Üres?(Konstans f:Fa):Logikai … hf. … Konstans Üres:Fa … hf. … Függvény EgyEleműFa(Konstans e:TElem):Fa … hf. … Függvény GyerekSzám(Konstans f:Fa):Egész Ha Üres?(BalGyerek(f)) akkor GyerekSzám:=0 különben GyerekSzám:=1+TestvérSzám(BalGyerek(f)) Elágazás vége Függvény vége. Függvény TestvérSzám(Konstans f:Fa):Egész … hf. … Megállapodás: Balra a leszármazottak, jobbra a testvérek. Lásd az ötletet. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Eljárás Beilleszt(Változó mire:Fa, Konstans mit:Fa): Ha Üres?(BalGyerek(mire)) akkor BalraIlleszt(mire,mit) különben BeillesztTestvérnek(BalGyerek(mire),mit) Elágazás vége Eljárás vége. Eljárás BeillesztTestvérnek(Változó mire:Fa, Konstans mit:Fa): Ha Üres?(JobbGyerek(mire)) akkor JobbraIlleszt(mire,mit) különben BeillesztTestvérnek(JobbGyerek(mire),mit) Elágazás vége Eljárás vége. Függvény GyökérElem(Konstans f:Fa):TElem … hf. … 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 6.3 B-fák Létrejöttének okairól: háttértár blokk-írás, -olvasás műveletek optimalizálása… A lényeg (-: béta-változata :-): Rögzített paraméter Típus B_Fa=Rekurzió(db:Egész,elem:Tömb(1..2*N-1:TElem), ág:Tömb(0..2*N-1:B_Fa)) [Típusinvariáns: bf:B_Fa: N>0  bf.db[N-1,2*N-1]  i[1..bf.db): bf.elemibf.elemi+1  bf.ág0.elem[Min’TElem..bf.elem1)  i[1..db): bf.ági.elem[bf.elemi..bf.elemi+1)  bf.ágbf.db.elem[bf.elembf.db..Max’TElem]] A „csak egy nem rekurzív ág” feltételtől eltekintünk! Egy „csöppnyi” baj: nem tartalmazhat N-1-nél kevesebb elemet?!? 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák Paraméteres típus. N – fizikai méret, k – logikai méret 2018.12.26. 6 Rekurzív adattípusok: fák Módosítás: A gyökér eltérő definiálása, kezelése. Előzetes definíciók: A B-fa elemben lévő értékek sorozata Típus TElemek(N,k)=Tömb(1..2*N-1:TElem) [Típusinvariáns: ek:TElemek: k[1..2*N-1]  Rendezettek(ek,k)] Def: Rendezettek(TElemek,Egész):L Rendezettek(x,k):=i[1..k): xi<xi+1 TB_FElemek(N,k,x)=Tömb(0..2*N-1:TB_FElem) [Típusinvariáns: bf:TB_FElemek: k[1..2*N-1]  x:TElemek(N,k)  RendezettFa(bf0, Min’TElem,x1)  i[1..k): RendezettFa(bfi, xi,xi+1)  RendezettFa(bfk, xk,Max’TElem)] Def: RendezettFa(TB_FElemek,TElem,TElem):L RendezettFa(f, a,b):=(f=  f.elem[a..b)) A B-fa elemben lévő B-fák sorozata 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák A B-fa definiálása: A gyökérelem A többi B-fa elemek B_Fa(N)=TB_Gyökér(N) TB_Gyökér(N)=Rekord(db:Egész,elem:TElemek(N,db), ág:TB_FElemek(N,db)) [Típusinvariáns: gy:TB_Gyökér: N>0  gy.db[1..2*N-1]] TB_FElem(N)=Rekurzió(db:Egész,elem:TElemek(N,db)), ág:TB_FElemek(N,db)) [Típusinvariáns:bf: B_Fa: N>0  bf.db[N-1..2*N-1]] A különbség: a db-mező értéktartománya!!! 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Pl.: N=3, akkor értékek száma: 2..5 1, 2 22, 25, 26 31, 32, 33, 38 11, 19 10, 20, 30 A definíció értelmes. Ui. N0 és elemszámra: B- fa. Lássunk néhány növekvő elemszámú példát: A frissen érkező elemet dőlt, árnyékos betűkkel jelöltük. 10 10;40 10;20;40 10;20;30;40 10;15;20;30;40 20 10;15;17 30;40 20 1;10;15;17 30;40 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Elvárások: ExportModul B_Fa(Típus TElem,TKulcs [TElem]): Konstans Üres:B_Fa Függvény Üres?(Konstans f:B_Fa):Logikai Függvény EgyeleműFa(Konstans e:TElem):B_Fa Eljárás Beilleszt(Változó f:B_Fa, Konstans e:TElem) [Ef: ef] Eljárás Keres(Konstans f:B_Fa, k:TKulcs, Változó van:Logikai, e:TElem) Eljárás Töröl(Változó f:B_Fa, Konstans k:TKulcs) [Ef: (k,?)f] Modul vége. 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák A megvalósítás: Az egyszerűség kedvéért eltérünk korábbi szigorú, „csak 1 nem rekurzív ág” feltételtől. Modul B_Fa(Típus TElem,TKulcs [TElem]): Reprezentáció Típus RBFa=Rekurzió(db:Egész,elem:Tömb(1..2*N:TElem), ág:Tömb(0..2*N-1:RBFa)) Változó bf:RBFa Implementáció Konstans Üres:B_Fa … hf. … Függvény Üres?(Konstans f:B_Fa):Logikai … hf. … Függvény EgyeleműFa(Konstans e:TElem):B_Fa … hf. … Eljárás Beilleszt(Változó f:B_Fa, Konstans e:TElem) [Ef: ef] … hf. … 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Eljárás Keres(Konstans f:B_Fa, k:TKulcs, Változó van:Logikai, e:TElem) … hf. … Eljárás Töröl(Változó f:B_Fa, Konstans k:TKulcs) [Ef: (k,?)f] … hf. … Inicializálás bf:=Üres Modul vége. A továbbiakban csak néhány példával illusztráljuk a beillesztés műveletét… 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 15;5 3 Új elem beillesztése – példával: 10; 20; 30 5; 10; 15; 20; 30 Telítődött: bontás 13 55;40;7;2 15 3; 5; 10 20; 30 15 2; 3; 5; 7; 10 20; 30; 40; 55 Telítődött: bontás 5; 15 2; 3 20; 30; 40; 55 7; 10; 13 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 22;95 Új elem beillesztése – példával (folytatás): 5; 15 2; 3 20; 30; 40; 55 7; 10; 13 Telítődött: bontás 5; 15; 30 2; 3 20; 22 7; 10; 13 40; 55; 95 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 1;6;0;-1 Új elem beillesztése – példával (folytatás): 5; 15; 30 2; 3 20; 22 7; 10; 13 40; 55; 95 4;29;50;71 5; 15; 30 -1; 0; 1; 2; 3 20; 22 6; 7; 10; 13 40; 55; 95 Telítődött: bontás 1; 5; 15; 30 -1; 0 20; 22; 29 6; 7; 10; 13 40; 50; 55; 71; 95 2; 3; 4 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák 45 Új elem beillesztése – példával (folytatás): 1; 5; 15; 30 -1; 0 20; 22; 29 6; 7; 10; 13 40; 50; 55; 71; 95 2; 3; 4 Telítődött: bontás 1; 5; 15; 30; 55 -1; 0 20; 22; 29 6; 7; 10; 13 40; 45; 50 2; 3; 4 71; 95 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Gyökér tele: „ok nélküli” bontás 8 Új elem beillesztése – példával (folytatás): 1; 5; 15; 30; 55 -1; 0 20; 22; 29 6; 7; 10; 13 40; 45; 50 2; 3; 4 71; 95 1; 5 -1; 0 20; 22; 29 6; 7; 8; 10; 13 40; 45; 50 2; 3; 4 71; 95 30; 55 15 2018.12.26. Rekurzió 4 Rekurzió 1

6 Rekurzív adattípusok: fák 2018.12.26. 6 Rekurzív adattípusok: fák Összefoglalva: Ha a B-fa elembe belefér, beszúrjuk. Ha tele van, arányosan kettévágjuk, a középsőt eggyel feljebb beszúrjuk; s így már helyre tehető az elem. Szintterebélyesedés. Ha a gyökér tele van, biztos-ami-biztos, előre ketté-vágjuk; s egy új gyökérelem képződik a kettévágandó középső elemével feltöltve. Szintszám-növekedés. A beszúrás O(N*logNK) blokkolvasással jár, ahol N a minimum fokszám (azaz egy B-fa elembe minimálisan tart-ható értékek száma-1), K a fában lévő értékek (TElem) száma. 2018.12.26. Rekurzió 4 Rekurzió 1