Az előadás letöltése folymat van. Kérjük, várjon

Az előadás letöltése folymat van. Kérjük, várjon

2. A rekurzió mint típuskonstrukció Szlávi Péter ELTE Média- és Oktatásinformatikai Tanszék 2009.

Hasonló előadás


Az előadások a következő témára: "2. A rekurzió mint típuskonstrukció Szlávi Péter ELTE Média- és Oktatásinformatikai Tanszék 2009."— Előadás másolata:

1 2. A rekurzió mint típuskonstrukció Szlávi Péter ELTE Média- és Oktatásinformatikai Tanszék 2009

2  A rekurzió mint típuskonstrukció 22/73 Tartalom 1 Bináris fák 1.0 Példák, alapfogalmak 1.1 Algebrai specifikáció 1.2 Exportmodul 1.3 Megvalósítási modul 1.4 Egy másik elképzelés 1.5 Összetett műveletek 1.6 Kereső fák 1.7 Rendező fák 2 Nem bináris fák 2.1 Algebrai specifikáció 2.2 Exportmodul 2.3 Megvalósítási modul Csak érdekességként

3  A rekurzió mint típuskonstrukció 23/73 1 Bináris fák 1.0 Példák, alapfogalmak  Kifejezések Kifejezések  Családfák Családfák  Kereső fák (amik a gyors megtalálást célozzák)  Rendező fák („virtuális fa” -- időleges állapot)

4  A rekurzió mint típuskonstrukció 24/73 Megjegyzés: Kifejezések sin(b(i)+a*x) „szabad szintaxisú” operátor (indexelés) prefix operátor (sin) + *Ind bi Sin ax * b + a2 := x x:=(a+2)*b nem kommutatív bináris operátor

5  A rekurzió mint típuskonstrukció 25/73 Megjegyzés: családfák John Ronald Reuel Tolkien családfája Ejnye. Ez nem is bináris!?!:-) Ejnye. Ez nem is bináris!?! :-)

6  A rekurzió mint típuskonstrukció 26/73 Megjegyzés: családfák A Tolkien család „leszármazási erdeje” (részlet) Mandy T Royd T Ruth T Hugh Baker Joan T Michael T Jan Turner Joan Griffits Michael T Edith Bratt J.Ronald R. T Hilary A.R. T Mabel Suffield Arthur R. T Jelmagyarázat: Kékek a fiúk; oválisban a há- zastársak.

7  A rekurzió mint típuskonstrukció 27/73 1 Bináris fák 1.1 Algebrai specifikáció Típus BinFa(Elem): Asszociált műveletek: 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] 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} *Illeszt(mire,mit)

8  A rekurzió mint típuskonstrukció 28/73 1 Bináris fák Jelölések 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ágAxió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))

9  A rekurzió mint típuskonstrukció 29/73 1 Bináris fák 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

10  A rekurzió mint típuskonstrukció 210/73 1 Bináris fák 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 [Ef: az f nem üres] Függvény JobbGyerek(Konstans f:BinFa ):BinFa [Ef: az f nem üres] …

11  A rekurzió mint típuskonstrukció 211/73 1 Bináris fák Eljárás GyökérMódosít(Változó f:BinFa,Konstans e:TElem) [Ef: az f nem üres] … 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.

12  A rekurzió mint típuskonstrukció 212/73 1 Bináris fák 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árarekord-szemléletű 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(RBinFa’Üres) 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

13  A rekurzió mint típuskonstrukció 213/73 1 Bináris fák … 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

14  A rekurzió mint típuskonstrukció 214/73 1 Bináris fák … Függvény BalGyerek(Konstans f:RBinFa):RBinFa [Ef:  RBinFa’Üres?(f)] BalGyerek:=f.bal Eljárás vége. Függvény JobbGyerek(Konstans f:RBinFa):RBinFa [Ef:  RBinFa’Üres?(f)] 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.

15  A rekurzió mint típuskonstrukció 215/73 1 Bináris fák 1.4 Egy másik elképzelés a megvalósításra Alapja a rekurzió típus „tulajdonos-számlálásos” ábrázolási módszere. ( Lásd az előző előadásban. )előadásban Modul BinFa(Típus TElem): Reprezentáció 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)

16  A rekurzió mint típuskonstrukció 216/73 1 Bináris fák 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 [Ef:  bf] 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) [Ef: bf  ] Függvény BalFa(Változó bf:TBinFa):TBinFa [Ef: bf  ] Függvény JobbFa(Változó bf:TBinFa):TBinFa [Ef: bf  ] Algoritmikus nyelvünk modulfogalma szerint az inicializáláskor üres értket kap. Így a  bf ef. kezdetben is tud teljesülni. bf≠    bf  bf.gyökér≠Sehova

17  A rekurzió mint típuskonstrukció 217/73 1 Bináris fák  „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]

18  A rekurzió mint típuskonstrukció 218/73 1 Bináris fák  „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) [Ef: -] Eljárás _BalraIlleszt_(Változó bf:TBinFa, Konstans mit:TBinFa) [Ef: bf  ] Eljárás _JobbraIlleszt_(Változó bf:TBinFa, Konstans mit:TBinFa) [Ef: bf  ] 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.

19  A rekurzió mint típuskonstrukció 219/73 1 Bináris fák  … é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) _BalraIlleszt_(bf,sbf) sbf:=bf.JobbFa TulajNövelés(sbf) _JobbraIlleszt_(bf.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) _BalraIlleszt_(bf,sbf) sbf:=bf.JobbFa TulajCsökkentés(sbf) _JobbraIlleszt_(bf,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.

20  A rekurzió mint típuskonstrukció 220/73 1 Bináris fák Még egyszer a BinFa-műveletkészlet használat- „módszertana”:  mikor, melyik művelet használandó,  módszertani elvek?Szabályok: 1. Minden deklarált BinFa adatobjektumot inicia- lizálni kell (Üres, EgyeleműFa konstruktorokkal). 2. 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. 3. Kerülendő a „sima” értékadás, helyette az Érté- ketKap-ot kell használni. Ha ez automatikusan nem történt meg.

21  A rekurzió mint típuskonstrukció 221/73 1 Bináris fák Illusztrálásképpen kövessük és értelmezzük a követ- kező programot:  ! 

22  A rekurzió mint típuskonstrukció 222/73 1 Bináris fák Töltse le az 1. exe-t és a exe 2. hozzátartozó listafájlt (14.txt)!listafájl … és próbálja ki! Csak a lépés gombot kell nyomogatni, ill. ha kíváncsi a megjegyzéseimre, akkor jelölje be az erre vonatkozó jelölőt! A 14. lépéshez tartozik a programlista, amely a megfelelő pillanatban egy külön ablakban jelenik meg, hogy lássa, és értelmezni tudja az állapotváltozásokat.

23  A rekurzió mint típuskonstrukció 223/73 1 Bináris fák 1.5 Összetett műveletek  Elemszám  Elemszám:  Mélység  Mélység: … hf … 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 Függvény 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 Függvény vége. Specifikáció – az uf. definíciós része Algoritmus

24  A rekurzió mint típuskonstrukció 224/73 1 Bináris fák  Bejárások Eljárás BKJ(Konstans bf:BinFa): Ha nem Üres?(bf) akkorBKJ(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) akkorKi: 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) akkorBJK(BalGyerek(bf)) BJK(JobbGyerek(bf)) Ki: GyökérElem(bf) Elágazás vége Eljárás vége.

25  A rekurzió mint típuskonstrukció 225/73 1 Bináris fák  A bejárások iteratív változatai Bal-közép-jobb Az algoritmus, először „kézzel”: * b + a2 := x

26  A rekurzió mint típuskonstrukció 226/73 1 Bináris fák  A bejárások iteratív változatai Az algoritmus, vázlatosan: … 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 … Még nem másodszor értünk vissza a gyökérhez Nem léptünk le egy levélről, azaz van út előre * b + a2 := x

27  A rekurzió mint típuskonstrukció 227/73 1 Bináris fák … é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 … Kövessük az algoritmust üres és üres és egyelemű binfára! egyelemű binfára!

28  A rekurzió mint típuskonstrukció 228/73 1 Bináris fák Közép-bal-jobb … hf … Bal-jobb-közép … hf …

29  A rekurzió mint típuskonstrukció 229/73 1 Bináris fák 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 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 ] Rövid leírhatóság kedvéért, átnevezzük: TKFa A „kereső fa”-tulajdonság

30  A rekurzió mint típuskonstrukció 230/73 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 ] KulcsegyértelműségKulcsegyértelműség 1 Bináris fák Rekord-szerűen (szigorúbb értelmezés): Definíciós ok miatt: a rendezés szerinti helyére kerül az e elem!

31  A rekurzió mint típuskonstrukció 231/73 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)] KulcsegyértelműségKulcsegyértelműség 1 Bináris fák L. később! később

32  A rekurzió mint típuskonstrukció 232/73 1 Bináris fák 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)] Kimenő értéke a kf-nek

33  A rekurzió mint típuskonstrukció 233/73 1 Bináris 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  e  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

34  A rekurzió mint típuskonstrukció 234/73 1 Bináris fák Megvalósítások: KeresésKeresé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énKeresés:=kf k GyökérElem(kf).kulcseseténKeresés:= Keresés(k,JobbGyerek(kf)) k=GyökérElem(kf).kulcseseténKeresés:=kf Elágazás vége Függvény vége.

35  A rekurzió mint típuskonstrukció 235/73 1 Bináris fák Sokaság-szerűen: 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

36  A rekurzió mint típuskonstrukció 236/73 1 Bináris fák Ugyanezt Rekord-szerűen is lehet: 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’… … 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.

37  A rekurzió mint típuskonstrukció 237/73 1 Bináris fák TörlésTö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.típusinvariancia 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éselemzés  lásd a „nincs jobboldali …” esetet  elemzéselemzés

38  A rekurzió mint típuskonstrukció 238/73 Megjegyzés: Nincs jobb részfa kf= bf kf= bf

39  A rekurzió mint típuskonstrukció 239/73 Megjegyzés: Mindkét részfa kf= bf jf bf jf

40  A rekurzió mint típuskonstrukció 240/73 1 Bináris 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), 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.

41  A rekurzió mint típuskonstrukció 241/73 1 Bináris 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

42  A rekurzió mint típuskonstrukció 242/73 1 Bináris 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ármazottait. Lásd az alábbi magyarázó ábrát: 9 ős 4 törlendő

43  A rekurzió mint típuskonstrukció 243/73 1 Bináris 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. Azaz az akt melyik szelektorán lóg a törlendő k kulcsú

44  A rekurzió mint típuskonstrukció 244/73 1 Bináris fák KiegyensúlyozásKiegyensúlyozás A probléma forrása… Definíciók: 1.Kiegyensúlyozott az a bináris fa, amelynek tetszőleges pontjá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ökerező” 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. ((1)2(3)) és (1(2(3))) „lényegében” ugyanazt a keresőfát jelöli, de mégis mennyire más

45  A rekurzió mint típuskonstrukció 245/73 1 Bináris fák 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 f3f3 f2f2 f1f1 ? új elem x y f3f3 f2f2 f1f1 ?

46  A rekurzió mint típuskonstrukció 246/73 1 Bináris 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 y f4f4 f2f2 f1f1 ? új elem x z f4f4 f2f2 f1f1 ? z f3f3 y f3f3

47  A rekurzió mint típuskonstrukció 247/73 1 Bináris fák 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úlyozottságra kell töre- kedni.) Á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

48  A rekurzió mint típuskonstrukció 248/73 1 Bináris 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

49  A rekurzió mint típuskonstrukció 249/73 1 Bináris fák Az exportmodul ésexportmodul 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ó …

50  A rekurzió mint típuskonstrukció 250/73 1 Bináris fák alapelv 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 „teljes” paraméterfát eredményezi, de a fa aktuális eleme bal „irányba” lép egyet…

51  A rekurzió mint típuskonstrukció 251/73 1 Bináris 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

52  A rekurzió mint típuskonstrukció 252/73 1 Bináris fák … 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. … előző gyökér|akt új gyökérakt gyökér|akt Elem bal | jobb | vissza új gyökérakt gyökér|akt Elem bal | jobb | vissza Egy elem törlése: … hf. …

53  A rekurzió mint típuskonstrukció 253/73 1 Bináris fák Maga a rendezett sorozat: (=BKJ-bejárással)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) Ki: GyökérElem(sf) Ciklus vége sf:=JobbGyerek(sf) Ciklus vége Eljárás vége

54  A rekurzió mint típuskonstrukció 254/73 1 Bináris fák A rendezés „irányától” függően 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 BalGyerek(i)=2*i JobbGyerek(i)=2*i+1 L. A korábbi előadást. előadás

55  A rekurzió mint típuskonstrukció 255/73 6 Rekurzív adattípusok: fák A kupac-rendezés „működése” ( példa ): A rendezendő sorozat A kupacosítás:

56  A rekurzió mint típuskonstrukció 256/73 6 Rekurzív adattípusok: fák A rendezés: Ime a kupac! „Helyre-csere”! Kupac helyrehozás

57  A rekurzió mint típuskonstrukció 257/73 6 Rekurzív adattípusok: fák „Helyre-csere”! Kupac helyrehozás „Helyre-csere”! Kupac helyrehozás

58  A rekurzió mint típuskonstrukció 258/73 6 Rekurzív adattípusok: fák „Helyre-csere”! Kupac helyrehozás „Helyre-csere”! Kupac helyrehozás „Helyre-csere”!

59  A rekurzió mint típuskonstrukció 259/73 6 Rekurzív adattípusok: fák Kupac helyrehozás „Helyre-csere”! A rendezett sorozat

60  A rekurzió mint típuskonstrukció 260/73 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.

61  A rekurzió mint típuskonstrukció 261/73 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é 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 csere miatt elromlott „fa" kupacosítása a j. elem „lecsúsztatása" a kupac- hosszadik elemig bezárólag

62  A rekurzió mint típuskonstrukció 262/73 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énMingyerek:=BalGyerek(elem) Érték(BalGyerek(elem))<Érték(JobbGyerek(elem)) eseténMingyerek:=BalGyerek(elem) egyéb esetbenMingyerek:=JobbGyerek(elem) Elágazás vége Függvény vége.

63  A rekurzió mint típuskonstrukció 263/73 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))= =  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 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. 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énMingyerek:=BalGyerek(elem) Érték(BalGyerek(elem))<Érték(JobbGyerek(elem)) eseténMingyerek:=BalGyerek(elem) egyéb esetbenMingyerek:=JobbGyerek(elem) Elágazás vége Függvény vége.

64  A rekurzió mint típuskonstrukció 264/73 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)

65  A rekurzió mint típuskonstrukció 265/73 2 Nem bináris fák 2.1 Algebrai specifikáció Típus Fa(Elem): Asszociált műveletek: 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)

66  A rekurzió mint típuskonstrukció 266/73 2 Nem bináris fák Jelölések 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ágAxió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))

67  A rekurzió mint típuskonstrukció 267/73 2 Nem bináris fák 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

68  A rekurzió mint típuskonstrukció 268/73 2 Nem bináris fák 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ó] …

69  A rekurzió mint típuskonstrukció 269/73 2 Nem bináris 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.

70  A rekurzió mint típuskonstrukció 270/73 2 Nem bináris fák 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, ÜresSorozat, ElemSzám, ElemSzám, Végére, Végére, (i) (i)

71  A rekurzió mint típuskonstrukció 271/73 2 Nem bináris 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) akkorGyerek:=f.ág(i) különbenGyerek:=Ü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.

72  A rekurzió mint típuskonstrukció 272/73 2 Nem bináris 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)BinFa 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, Balra a leszármazottak, jobbra a testvérek. jobbra a testvérek. Lásd az ötletet. ötletet

73  A rekurzió mint típuskonstrukció 273/73 2 Nem bináris fák Egy alternatív megoldás ötlete: Balra az „1.” gyerek Jobbra a „következő” testvér


Letölteni ppt "2. A rekurzió mint típuskonstrukció Szlávi Péter ELTE Média- és Oktatásinformatikai Tanszék 2009."

Hasonló előadás


Google Hirdetések