370 likes | 489 Views
A rekurzió mint típuskonstrukció. 1. Szlávi Péter ELTE Média- és Oktatásinformatikai Tanszék szlavip@elte.hu http://people.inf.elte.hu/szlavi 2009. 1 Nevezetes rekurzív adatszerkezetek 2 Rekurzív adatszerkezetek definiálása 1.1 A rekurzió mint sokaság 1.2 A rekurzió mint rekord-analogon
E N D
A rekurzió mint típuskonstrukció 1. Szlávi Péter ELTE Média- és Oktatásinformatikai Tanszék szlavip@elte.huhttp://people.inf.elte.hu/szlavi 2009
1 Nevezetes rekurzív adatszerkezetek 2 Rekurzív adatszerkezetek definiálása 1.1 A rekurzió mint sokaság 1.2 A rekurzió mint rekord-analogon 3 A struktúrabejárás mint a feldolgozás „kerete” Tartalom A rekurzió mint típuskonstrukció 1.
ÜresListaLista := Egyesítés(Elem,Lista) ÜresFaBinFa:= Egyesítés(Elem,BinFa,BinFa) ÜresFaFa := Egyesítés(Elem,Fák) 1 Nevezetes rekurzív adatszerkezetek A sokaságoknál definiált Üresművelet. A sokaságoknál definiált Egyesítésművelet. A rekurzió mint típuskonstrukció 1.
Az Egyesítéskét értelmezési lehetősége („filozófia”): sokaság (a mikroszerkezet hangsúlyozása: azonos típusú Elemekből épül föl valahogyan) egy „furcsa” direktszorzat(a makroszerkezet hangsú-lyozása: egyenrangú, de nem azonos típusú részekből, még-pedig Elemből és valami,az egészre emlékeztetőből áll). A részek elérésének programozástechnikája: értékmegosztással (láncolással/mutatóval) értékmásolással. 1 Nevezetes rekurzív adatszerkezetek A rekurzió mint típuskonstrukció 1.
A rekurzív adatszerkezet jellemzői: sokaság: azonos típusú elemekből áll akár 0 db elemet tartalmazhat Üres: rekurzív „nullelem”, kitüntetett konstans Fraktál (=önhasonlóság) tulajdonság: a részei ugyanolyan szerkezetűek, mint az egész nem lineárisan rendezett (azaz nem sorozatféle): bármely elemének 0, 1, 2… (közvetlen) rákövetke-zője lehet; bár minden elemnek legfeljebb egy (közvetlen) előzője van. 1 Nevezetes rekurzív adatszerkezetek A rekurzió mint típuskonstrukció 1.
2.0 Rekurzió egy típuskonstrukciós eszköz Megjegyzések: Csak 1 nem rekurzív komponens („mező”) lehet.(Ez nem valódi korlátozás!!!) A rekurzív komponensek típusa a „teljes” (definiálandó) típussal kötelezően megegyező. Szelektorok elő fognak fordulni paraméterként, ezért bevezetjük a Szelektor kulcs-szót. (Tulajdonképpen egy spec. típus, l. később.) 2 Rekurzív adatszerkezetek definiálása Típus TRek=Rekurzió (szelektor1:TElem szelektor2 :TRek …) Vö.: Szelektor Mutató-típusok A rekurzió mint típuskonstrukció 1.
Nem véletlen a szintaktikai hasonlóság a rekorddal. A műveleteik is sokban emlékeztetnek majd egymásra. Sajátos gond: nehéz az „egzakt” szintaxisú leírása. Oka –akárcsak a rekordnál–: a tetszőleges számú paraméter (bár itt csak kétféle típusú lehet). 2 Rekurzív adatszerkezetek definiálása A rekurzió mint típuskonstrukció 1.
Példák: 2 Rekurzív adatszerkezetek definiálása Sokaság filozófiájával aposztrofálva a rekurzív ágat: Típus TLista=Rekurzió (elem:TElemköv:TLista) Típus TLista=Rekurzió (elem:TElem farok:TLista) Típus TBinFa=Rekurzió (elem:TElem bal, jobb:TBinFa) Típus TFa=Rekurzió (elem:TElem ágak:Sorozat(TFa)) A Sorozat csak jelzése valamely ismert sorozatfélének (Tömb, AbsztraktSorozat …) A rekurzió mint típuskonstrukció 1.
2.1 Rekurzió mint sokaság Sajátossága: A rekurzió elemek sokasága, így szükséges lesz kezeléséhez egy kezdő (gyökér)-elemre (amely a teljes szerkezetet „összetartja”), egy aktuális elemre (amelyre a legtöbb művelet vonat-kozni fog). 2 Rekurzív adatszerkezetek definiálása Az algebrai specifikáció: hf. A rekurzió mint típuskonstrukció 1.
2.1.1 A rekurzió exportmodulja a modulfejben tisztázni kell a felhasználás szinta-xisát, de ezt most nem lehet teljesen egzaktmódon, mivel változó számú paraméterrel rendelkezik. 2 Rekurzív adatszerkezetek definiálása Típus TRek= Rekurzió(eszel:TElem,rszel1,…:TRek) ExportModul Rekurzió(eszel:TElem,rszel1,…:TRek): Formálisabban (szintaktikus ellenőrzés lehetőségét lehetővé téve):ExportModul Rekurzió(Konstans eszel:Szelektor, Típus TElem,Konstans rszel1,…:Szelektor, Típus TRek):Másként Rekurzió(eszel:TElem,rszel1,…:TRek) A hívás szintaxisa A rekurzió mint típuskonstrukció 1.
Kísérlet az exportmodul „egzakttá” tételére: * bináris fa rekurzív típusának definiálása: * … és exportmodulja: Lényeg: a típuskonstrukciónál csak a minimálisan szük-séges számú paraméter szerepeljen! Nem erőltetjük a rekurzivitás explicit kifejezését. 2 Rekurzív adatszerkezetek definiálása Típus TBFSzel=(elem,bal,jobb) [felsorolási típus] TElem=… TBF=Rekurzió(TElem,TBFSzel) ExportModul Rekurzió(Típus TElem, Típus TRSzel): [hivatkozás a(z) * nem rekurzív komponensre: Min’TRSzel szelektorral * 1. rekurzív komponensre: Következő(Min’TRSzel) * … * utolsó rekurzív komponensre: Max’TRSzel] A rekurzió mint típuskonstrukció 1.
Exportmodul: 2 Rekurzív adatszerkezetek definiálása Most a szokásos, nem teljesen egzakt jelöléssel folytatjuk. ExportModul Rekurzió(eszel:TElem,rszel1 …:TRek): Függvény Üres?(Konstans r:TRek):Logikai [Uf: a „teljes” r üres-e?] Konstans Üres:TRek [Uf: 0 db elemből álló struktúra] Eljárás Létrehoz(Konstans e:TElem, Változó r:TRek) [Uf: r 1-elemű rekurzív struktúra]Megjegyzés: nem küszöbölhető ki, ui.: azIlleszt az egyetlen „bővítő” operátor, ami bővíteni csak akkor tud, ha legalább 1-elemű rekurzív struktú- rákkal manipulál. Eljárás Illeszt(Konstans mit:TRek, Változó mihez:TRek, Konstans melyik:Szelektor) [Ef: Üres?(mihez) vagy Üres?(Rész(mihez,melyik)Uf: Két azonos típusú rekurzív szerkezetet egymáshoz illeszt, a mihezakt-jánál, a melyik-en keresztül] Precízebben:Szelektor’TRek A rekurzió mint típuskonstrukció 1.
2 Rekurzív adatszerkezetek definiálása Eljárás Leválaszt(Változó miről:TRek, Konstans melyik:Szelektor,Változó mire:TRek) [Ef: Üres?(mire) Uf: a miről leválasztja az akt melyik szelektorán kapcsolódó részt, s a mire akasztja; az adott ágat üressé teszi] Függvény Elem(Konstans r:TRek):TElem [Uf: az akt elem értéke] Függvény Rész(Konstans minek:TRek, melyik:Szelektor):TRek [Uf: a minek struktúra az akt-ról a melyik szelektorán „lógó” rész-struktúrát adja vissza értékmegosz- tással, azaz annak a memóriacímét, mutatóját] Eljárás Lemásol(Konstans mit:TRek, Változó mire:TRek) [Ef: Üres?(mire) Uf: mitakt-ból kiinduló rész pontos másolatát a mire akasztja] A rekurzió mint típuskonstrukció 1.
Nem mondtuk ki, legtöbb operáció előfeltételének elvárt része:létezzék az akt elem, és melyik≠Min’Szelektor! 2 Rekurzív adatszerkezetek definiálása Eljárás Felszabadít(Változó r:TRek) [Uf: felszabadítja az akt-ból eredő rész-struktúra által lefoglalt memóriaterületet] Eljárás Módosít(Konstans e:TElem, Változó r:TRek) [Uf: az r akt elemét e-re módosítja] Eljárás Elsőre(Változó r:TRek) [Uf: a gyökért teszi aktuálissá]Eljárás Következőre(Változó r:TRekKonstans melyik:Szelektor) [Uf: az akt elem melyik szelektorán továbblép, ha lehet] Függvény Elején?(Konstans r:TRek):Logikai [Uf: az akt elem a struktúra gyökéreleme-e?]Függvény Végén?(Konstans r:TRek):Logikai [Uf: az akt elem valamelyik terminális elem-e?] Modul vége. A rekurzió mint típuskonstrukció 1.
2.1.2 A rekurzió megvalósítási modulja Reprezentáció – láncolt: 2 Rekurzív adatszerkezetek definiálása Ez a típus „glo-bális” neve is. Modul Rekurzió(eszel:TElem,rszel1,…:TRek):Reprezentáció [láncolt] Típus TRElem=Rekord(eszel:TElem, rszel1, … :TRElem’Mutató) TRek=Rekord(gyökér:TRElem’Mutató akt:TRElem’Mutató hiba:Logikai)Változó r:TRek Pascal-ban: ^TRElem Ez dönt a típus me-mórialefoglalásról. A rekurzió mint típuskonstrukció 1.
Implementáció: 2 Rekurzív adatszerkezetek definiálása Implementáció Függvény Üres?(Konstans r:TRek):Logikai Üres?:=r.gyökér=Sehova Függvény vége. Konstans Üres:TRek(Sehova,Sehova,Hamis) Eljárás Létrehoz(Konstans e:TElem, Változó r:TRek): Lefoglal(r.gyökér,TRElem(e,Sehova,…)) Eljárás vége. A rekurzió mint típuskonstrukció 1.
2 Rekurzív adatszerkezetek definiálása Eljárás Illeszt(Konstans mit:TRek, Változó mihez:TRek, Konstans melyik:Szelektor): [Ef: mihez.gyökér=Sehova (mihez.aktSehova melyik≠eszel TRElem(mihez.akt).melyik=Sehova)]Elágazás Üres?(mihez) esetén mihez:=mitegyébesetben TRElem(mihez.akt).melyik:=mit.gyökér Elágazás vége Eljárás vége. Eljárás Leválaszt(Változó miről:TRek, Konstans melyik:Szelektor,Változó mire:TRek): [… hf …] Jól-definiáltság Hogy ne vesszen el elem Pascal-ban: mihez.akt^.melyik A rekurzió mint típuskonstrukció 1.
2 Rekurzív adatszerkezetek definiálása Függvény Elem(Konstans r:TRek):TElem [Ef: r.akt≠Sehova] Elem:=TRElem(r.akt).eszelFüggvény vége. Függvény Rész(Konstans minek:TRek, melyik:Szelektor):TRek [Ef: minek.akt≠Sehova melyik≠eszel] Rész:=TRek(TRElem(minek.akt).melyik [gyökér] TRElem(minek.akt).melyik [akt], Hamis) Függvény vége. Eljárás Lemásol(Konstans mit:TRek, Változó mire:TRek): [… hf …]Eljárás Felszabadít(Változó r:TRek) [… hf … Figyelem: értékmegosztás miatt többszörös felhasználás lehetséges!!! (hivatkozás-számláló)] Eljárás Módosít(Konstans e:TElem, Változó r:TRek): [Ef: r.akt≠Sehova] TRek(r.akt).eszel:=eEljárás vége. A rekurzió mint típuskonstrukció 1.
2 Rekurzív adatszerkezetek definiálása Eljárás Elsőre(Változó r:TRek): [Ef: r.akt≠Sehova r.gyökér≠Sehova] r.akt:=r.gyökérEljárás vége. Eljárás Következőre(Változó r:TRek,Konstans melyik:Szelektor): [Ef: r.akt≠Sehova melyik≠eszel TRElem(r.akt).melyikSehova]r.akt:=TRElem(r.akt).melyik Eljárás vége. Függvény Elején?(Konstans r:TRek):Logikai [… hf …]Függvény Végén?(Konstans r:TRek):Logikai [… hf …] Inicializálás r:=ÜresModul vége. A rekurzió mint típuskonstrukció 1.
Példaként egy érték megkereséseaTRektípuskonstrukció műveleteire építve: 2 Rekurzív adatszerkezetek definiálása Függvény RekKer(Konstans r:TRek, e:TElem):TRek [Ef: – vagy Elején?(r) Uf: er Elem(RekKer(r,e))=e Elején?(RekKer(r,e)) er Üres?(RekKer(r,e))]Változómelyik:Szelektor’TRek kész:Logikai rm:TRekHa Üres?(r) akkor RekKer:=Üreskülönben … A rekurzió mint típuskonstrukció 1.
2 Rekurzív adatszerkezetek definiálása … különbenHa Elem(r)=e akkor RekKer:=rkülönben melyik:=Következő(Min’Szelektor’TRek) kész:=HamisCiklus amíg melyikMax’Szelektor’TRek és nem kész rm:=RekKer(Rész(r,melyik),e) kész:=nem Üres?(rm) [és Elem(rm)=e]Ha melyik<Max’Szelektor’TRek akkor melyik:=Következő(melyik)különben kész:=Igaz Elágazás vége Ciklus vége RekKer:=rmElágazás végeElágazás végeFüggvény vége. A nem rekurzív mező szelektora. A rekurzió mint típuskonstrukció 1.
Az értékmegosztás problematikájának egy példája: bf Rész(bf,bal) Leválaszt(Rész(bf,bal),bal,bf2) Rész(bf,bal),bal 2 Rekurzív adatszerkezetek definiálása Abf„kétszeresen balra eső” részfájának leválasztása:Elsőre(bf);Leválaszt(Rész(bf,bal),bal,bf2) Elsőre(bf) A rekurzió mint típuskonstrukció 1.
A helyfelszabadítás és az értékmegosztás problemati-kájának egy példája: bf jbf:=Rész(bf,jobb) 2 Rekurzív adatszerkezetek definiálása Kövessük az alábbi példát:Elsőre(bf); jbf:=Rész(bf,jobb); bf:=Rész(bf,bal) jÉrt:=Feldolgoz(jbf) [jbf változatlan] bÉrt:=Feldolgoz(bf) [bf változatlan] Felszabadít(jbf) Elsőre(bf) A rekurzió mint típuskonstrukció 1.
A helyfelszabadítás és az értékmegosztás problemati-kájának egy példája: jbf 2 Rekurzív adatszerkezetek definiálása Kövessük az alábbi példát: Elsőre(bf); jbf:=Rész(bf,jobb); bf:=Rész(bf,bal) jÉrt:=Feldolgoz(jbf) [jbf változatlan] bÉrt:=Feldolgoz(bf) [bf változatlan] Felszabadít(jbf) bf bf:=Rész(bf,bal) A rekurzió mint típuskonstrukció 1.
A helyfelszabadítás és az értékmegosztás problemati-kájának egy példája: jbf 2 Rekurzív adatszerkezetek definiálása Kövessük az alábbi példát: Elsőre(bf); jbf:=Rész(bf,jobb); bf:=Rész(bf,bal)jÉrt:=Feldolgoz(jbf) [jbf változatlan] bÉrt:=Feldolgoz(bf) [bf változatlan] Felszabadít(jbf) bf jÉrt:=Feldolgozás(jbf); bÉrt:=Feldolgozás(bf) A rekurzió mint típuskonstrukció 1.
A helyfelszabadítás és az értékmegosztás problemati-kájának egy példája: jbf 2 Rekurzív adatszerkezetek definiálása Kövessük az alábbi példát: Elsőre(bf); jbf:=Rész(bf,jobb); bf:=Rész(bf,bal) jÉrt:=Feldolgoz(jbf) [jbf változatlan] bÉrt:=Feldolgoz(bf) [bf változatlan]Felszabadít(jbf) bf Felszabadít(jbf) ? • Problémák: • A felszabadítás után „csellengő” hivatkozások keletkeznek! • Mi lesz az értékadás után a baloldali változó „egykori” értékével? A rekurzió mint típuskonstrukció 1.
Egy tisztességes megoldás ötlete: Hivatkozás- („tulajdonos”-)számlálás. Felszabadítás intelligensebbé tétele. Megvalósítás felé: Reprezentáció-módosítás minden rekurzív elemnek tulajdonos-számlálót Implementáció-módosítás (hol kell a számlálóval foglalkozni?) Értékadáskor Eljáráshíváskor a paraméterek vonatkozásában Függvényhíváskor a paraméterek, fv.-érték vonatkozásában Kifejezésekben Csak időleges értékmegosztás történik: (=nem kell) 2 Rekurzív adatszerkezetek definiálása Tartós értékmegosztás történik: A rekurzió mint típuskonstrukció 1.
Érdemes a részleteket meggondolni Pl. ab:=fv(bb)értékadást valósítsuk meg az Értékadás(b,fv(bb))eljárással. 2 Rekurzív adatszerkezetek definiálása Eljárás Értékadás(Változó b:TRek, Konstans bb:TRek): TulajdonostCsökkent(b)[b-től kiindulva az összes elem tulajdonos- számlálóját 1-gyel csökkenti, és a 0 tulajdonos-számúak helyét felszabadítja]b:=bb [címmegosztás] TulajdonostNövel(b) [b-től kiindulva az összes elem tulajdonos- számlálóját 1-gyel növeli] Eljárás vége. A rekurzió mint típuskonstrukció 1.
2.2 Rekurzió mint rekord-analogon Előzetes megjegyzések: ez az „igazi”, rekurzióhoz illeszkedő elképzelés a leírás nem teljesen „egzakt” formális okok miatt hihetetlenül egyszerű „nyelvezetű”, mindössze 4 műveletet definiálunk: Üres Üres? a mezőkhöz való értékhozzáférés a mezőkhöz való módosítási célú hozzáférés 2 Rekurzív adatszerkezetek definiálása Az algebrai specifikáció: hf. A rekurzió mint típuskonstrukció 1.
2.2.1A rekurzió exportmodulja 2 Rekurzív adatszerkezetek definiálása ExportModul Rekurzió(eszel:TElem,rszel1,…:TRek): Függvény Üres?(Konstans r:TRek):LogikaiKonstans Üres:TRekOperátorMező(Konstans r:TRek, melyik:Szelektor):TElem TRekMásnéven r.melyik [Ef: melyik=eszel melyik=rszel1 … Uf: az r melyik szelektora által kijelölt komponense, amely ha melyik=eszel, akkor TElem, ha melyik=rszeli, akkor TRek típusú] A rekurzió mint típuskonstrukció 1.
Gondolja meg, miért nincs szükség néhány korábbi műveletre;pl. az Elem, a Rész, a Következő műveletre? nem megvalósítható az Elsőre művelet? 2 Rekurzív adatszerkezetek definiálása OperátorLegyen(Változó r:TRek, Konstans melyik:Szelektor,er:TElem TRek)Másnéven r.melyik:=er [Ef: (melyik=eszel er:TElem) (melyik=rszeli er:TRek) Uf: az r melyik szelektora által kijelölt komponense értékül kapja az er-t, vagyis „r.melyik:=er”, amely ha melyik=eszel, akkor TElem, ha melyik=rszeli, akkor TRek típusú adatok között megy végbe]Modul vége. Hf: megoldani az új jelölésekkel. A rekurzió mint típuskonstrukció 1.
Egy „szintaktikai” példa: 2 Rekurzív adatszerkezetek definiálása Típus TBinFa=Rekurzió(ért:TElem, bal,jobb:TBinFa) Változó b1,b2:TBinFa e:TElem b1:=Üres; b2:=TBinFa(e,Üres,b1) [egy-elemű bifa] … e:=b2.ért; b1:=b2.bal [a binfa részeihez férés] … b1.ért:=e; b1.bal:=b2.jobb [binfa részek módosítása] … b2:=TBinFa(b1.ért,b1.jobb,b1.bal) [binfa-komponálás] A rekurzió mint típuskonstrukció 1.
2 Rekurzív adatszerkezetek definiálása Vö.: a sokaság-szerűvel! Modul Rekurzió(eszel:TElem,rszel1,…:TRek): Reprezentáció Típus TRElem=Rekord(eszel:TElem rszel1, …: TRElem’Mutató) TRek=TRElem’Mutató Változó r:TRek Implementáció Függvény Üres?(Konstans r:TRek):Logikai Üres?:=r=Sehova Függvény vége. Konstans Üres:TRek(Sehova) Operátor Mező(Konstans melyik:Szelektor, r:TRek):TElem TRekMásnéven r.melyik Mező:=TRElem(r).melyik Operátor Vége. Gondolja meg a hibaflag-gel bővítést! A rekurzió mint típuskonstrukció 1.
Megjegyzés: ez esetben is választható az „intelligens”, tulajdo-nos-számlálós implementáció, amely a TRek-típusú értékadások intelligens megvalósítását jelenti 2 Rekurzív adatszerkezetek definiálása Operátor Legyen(Változó r:TRek, Konstans melyik:Szelektor,er:TElem TRek)Másnéven r.melyik:=er TRElem(r).melyik:=er Operátor Vége.Inicializálás r:=ÜresModul vége. A rekurzió mint típuskonstrukció 1.
Feldolgozás sokaság-szemlélettel: Feldolgozás rekord-szemlélettel: 3 Struktúrabejárás mint a feldolgozás kerete Eljárás RFeld(Konstans r:TRek):Ha nem Üres?(r) akkor EFeld(Elem(r)) RFeld(Rész(r,rszel1)) RFeld(Rész(r,rszel2)) … Elágazás végeEljárás vége. Eljárás RFeld(Konstans r:TRek):Ha nem Üres?(r) akkor EFeld(r.eszel) RFeld(r.rszel1) RFeld(r.rszel2) … Elágazás végeEljárás vége. A rekurzió mint típuskonstrukció 1.
Példák: Listabejárás: 3 Struktúrabejárás mint a feldolgozás kerete Lehet tetszőleges elem-feldolgozás. Eljárás LBejár(Konstans l:TLista):Ha nem Üres?(l) akkor Ki: Elem(l) LBejár(Rész(l,farok))Eljárás vége. Elhagyható lenne! Hívása:Elsőre(l); LBejár(l) Eljárás LBejár(Konstans l:TLista):Ha nem Üres?(l) akkor Ki: l.elem LBejár(l.farok)Eljárás vége. Hívása:LBejár(l) A rekurzió mint típuskonstrukció 1.
az algoritmikus rekurzió iterációvá alakítása egyszerű a jobbrekurzió miatt: Végén?(sl) sl:=Következőre(sl,farok) 3 Struktúrabejárás mint a feldolgozás kerete Eljárás LBejár(Konstans l:TLista):Változó sl:TLista sl:=l; Elsőre(sl) Ciklus amíg nem Üres?(sl)Ki: Elem(l) sl:=Rész(sl,farok) Ciklus végeEljárás vége. Eljárás LBejár(Konstans l:TLista):Változó sl:TLista sl:=lCiklus amíg nem Üres?(sl)Ki: Elem(l) sl:=sl.Farok Ciklus végeEljárás vége. A rekurzió mint típuskonstrukció 1.