Rekurzió. Működése, programtranszformációk. Programozás II. előadás. Szénási Sándor.

Hasonló dokumentumok
Rekurzió. Témakörök. Rekurzió alapelve. Rekurzió alapjai Rekurzív algoritmusok végrehajtása Visszalépéses keresés Programtranszformációk

Rekurzió. (Horváth Gyula és Szlávi Péter előadásai felhasználásával)

Programozás II. előadás

B-fa. Felépítés, alapvető műveletek. Programozás II. előadás. Szénási Sándor.

Eseménykezelés. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor.

5. Rekurzió és iteráció (Rekurzív programok átírása nemrekurzívvá)

Eljárások és függvények

Programozás I. 1. előadás: Algoritmusok alapjai. Sergyán Szabolcs

Visszalépéses keresés

Programozás I. Sergyán Szabolcs Óbudai Egyetem Neumann János Informatikai Kar szeptember 10.

Rekurzió. Dr. Iványi Péter

Láncolt listák. Egyszerű, rendezett és speciális láncolt listák. Programozás II. előadás. Szénási Sándor

Algoritmusok, adatszerkezetek, objektumok

Programozás I. Sergyán Szabolcs Óbudai Egyetem Neumann János Informatikai Kar szeptember 10.

ALGORITMIKUS SZERKEZETEK ELÁGAZÁSOK, CIKLUSOK, FÜGGVÉNYEK

Optimalizációs stratégiák 1.

Összetett programozási tételek

Adatszerkezetek Tömb, sor, verem. Dr. Iványi Péter

Rekurzív algoritmusok

Programozás C- és Matlab nyelven C programozás kurzus BMEKOKAM603 Függvények. Dr. Bécsi Tamás 6. Előadás

Programozási nyelvek a közoktatásban alapfogalmak I. előadás

Verem Verem mutató 01

Gráfok 1. Tárolási módok, bejárások. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor

Rekurzió. (Horváth Gyula és Szlávi Péter előadásai. felhasználásával)

Bevezetés az informatikába

Haladó rendezések. PPT 2007/2008 tavasz.

A programozás alapjai előadás. Amiről szólesz: A tárgy címe: A programozás alapjai

Egyszerű programozási tételek

Rekurzió. (Horváth Gyula és Szlávi Péter előadásai felhasználásával)

Adatszerkezetek 1. Dr. Iványi Péter

Programozási nyelvek Java

Optimalizációs stratégiák 2.

Programozás I. Egyszerű programozási tételek. Sergyán Szabolcs

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { } -ek közti részt a Bash héj kód blokknak (code block) nevezi.

Alkalmazott modul: Programozás 4. előadás. Procedurális programozás: iteratív és rekurzív alprogramok. Alprogramok. Alprogramok.

Programozási tételek. PPT 2007/2008 tavasz.

A C programozási nyelv II. Utasítások. A függvény.

Programozás I. Egyszerű programozási tételek. Sergyán Szabolcs

Már megismert fogalmak áttekintése

Rendezések. Sergyán Szabolcs Óbudai Egyetem Neumann János Informatikai Kar október 24.

Informatika tanítási módszerek

Programozás alapjai. 7. előadás

Gráfok 2. Legrövidebb utak, feszítőfák. Szoftvertervezés és -fejlesztés II. előadás. Szénási Sándor

Rekurzió. (Horváth Gyula és Szlávi Péter előadásai felhasználásával)

Információs Technológia

Programozási nyelvek 6. előadás

OOP. Alapelvek Elek Tibor

Bináris keresőfa. Felépítés, alapvető műveletek. Programozás II. előadás. Szénási Sándor

A programozás alapjai

Programozási nyelvek a közoktatásban alapfogalmak II. előadás

Gráfok. Programozás II. előadás. Szénási Sándor.

Algoritmizálás, adatmodellezés tanítása 6. előadás

A verem (stack) A verem egy olyan struktúra, aminek a tetejéről kivehetünk egy (vagy sorban több) elemet. A verem felhasználása

Előfeltétel: legalább elégséges jegy Diszkrét matematika II. (GEMAK122B) tárgyból

Interfészek. PPT 2007/2008 tavasz.

5. előadás. Programozás-elmélet. Programozás-elmélet 5. előadás

Készítette: Nagy Tibor István Felhasznált irodalom: Kotsis Domokos: OOP diasor Zsakó L., Szlávi P.: Mikrológia 19.

5. Hét Sorrendi hálózatok

Hasító táblázatok. Hasító függvények, kulcsütközés kezelése. Programozás II. előadás. Szénási Sándor

Adatok ábrázolása, adattípusok

Programozás C nyelven 6. ELŐADÁS. Sapientia EMTE

Programozás BMEKOKAA146. Dr. Bécsi Tamás 5. előadás

Algoritmusok és adatszerkezetek gyakorlat 06 Adatszerkezetek

van neve lehetnek bemeneti paraméterei (argumentumai) lehet visszatérési értéke a függvényt úgy használjuk, hogy meghívjuk

és az instanceof operátor

Java programozási nyelv

Java VIII. Az interfacei. és az instanceof operátor. Az interfészről általában. Interfészek JAVA-ban. Krizsán Zoltán

29. Visszalépéses keresés 1.

A programozás alapjai 1 Rekurzió

Programozás alapjai. 6. gyakorlat Futásidő, rekurzió, feladatmegoldás

9. előadás. Programozás-elmélet. Programozási tételek Elemi prog. Sorozatszámítás Eldöntés Kiválasztás Lin. keresés Megszámolás Maximum.

A fordítóprogramok szerkezete. Kódoptimalizálás. A kódoptimalizálás célja. A szintézis menete valójában. Kódoptimalizálási lépések osztályozása

Fák Témakörök. Fa definíciója. Rekurzív típusok, fa adatszerkezet Bináris keresőfa, bejárások Bináris keresőfa, módosítás B-fa

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós október 11. Széchenyi István Egyetem, Gy r

Objektumorientált Programozás VI.

Programozás I. 5. Előadás: Függvények

Láncolt listák Témakörök. Lista alapfogalmak

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós március 3. Széchenyi István Egyetem, Gy r

Web-programozó Web-programozó

Bánsághi Anna 2014 Bánsághi Anna 1 of 33

Paraméter átadás regisztereken keresztül

Programozás alapjai II. (7. ea) C++ Speciális adatszerkezetek. Tömbök. Kiegészítő anyag: speciális adatszerkezetek

Speciális adatszerkezetek. Programozás alapjai II. (8. ea) C++ Tömbök. Tömbök/2. N dimenziós tömb. Nagyméretű ritka tömbök

Webprogramozás szakkör

Programkonstrukciók A programkonstrukciók programfüggvényei Levezetési szabályok. 6. előadás. Programozás-elmélet. Programozás-elmélet 6.

Adatszerkezetek Adatszerkezet fogalma. Az értékhalmaz struktúrája

Bevezetés a programozásba. 8. Előadás: Függvények 2.

Összetett programozási tételek Rendezések Keresések PT egymásra építése. 10. előadás. Programozás-elmélet. Programozás-elmélet 10.

Programozás alapjai II. (7. ea) C++

Algoritmizálás, adatmodellezés tanítása 1. előadás

Az összetett programozási tételek is egy tőről fakadnak

A félév során előkerülő témakörök

Objektumorientált paradigma és a programfejlesztés

Algoritmusok és adatszerkezetek I. 4. előadás

2018, Diszkrét matematika

Webprogramozás szakkör

Programozási alapismeretek 1. előadás

Fordítás Kódoptimalizálás

Algoritmizálás, adatmodellezés tanítása 1. előadás

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

Átírás:

Rekurzió Működése, programtranszformációk előadás http://nik.uni-obuda.hu/prog2 Szénási Sándor szenasi.sandor@nik.uni-obuda.hu Óbudai Egyetem,Neumann János Informatikai Kar

Rekurzió Rekurzió alapjai Rekurzív algoritmusok végrehajtása Programtranszformációk

Rekurzió alapelve szenasi.sandor@nik.uni-obuda.hu 3 Ahhoz, hogy megérthessük a rekurziót, először meg kell értenünk a rekurziót (ismeretlen szerző) Rekurzív algoritmusokat általában akkor használunk, ha az alapfeladat túl bonyolult, azonban rekurzív hívásokkal ezt vissza tudjuk vezetni egyszerűbb (rész)feladatok megoldására Ennek megfelelően egy rekurzív feladatot általában ehhez hasonlóan definiálunk: triviális megoldása általános eset egyszerűsítése Technikai értelemben rekurzív algoritmusnak azt tekintjük, ami közvetve (közvetlen rekurzió) vagy más függvények közbeiktatásával (közvetett rekurzió) meghívja önmagát

Rekurzív függvény felépítése szenasi.sandor@nik.uni-obuda.hu 4 Az előzőek alapján egy lehetséges definíció: f(x) = g(x) h f i(x) ha t(x) ha t(x) f(x) a rekurzív függvény t(x) triviális esethez jutottunk-e? g(x) triviális esetben a megoldás h(x) utólagos feldolgozás i(x) előzetes feldolgozás Feltételezzük, hogy bármelyik bemenetből a triviális megoldás biztosan, véges lépésből elérhető A függvény általában nem csak önmagát hívja, hanem ez előtt és után van lehetősége műveleteket végezni a továbbítandó paramétereken

5 Rekurzív függvény általános pszeudokódja Az előző oldalon látottaknak megfelelően: függvény Rekurzív(x) ha t(x) akkor Rekurzív g(x) különben a i(x) b Rekurzív(a) c h(b) Rekurzív c elágazás vége A pszeudokódban található függvényhívások értelemszerűen feladattól függően jelenthetnek tetszőleges összetett műveletet A fenti csak egy általános minta, a konkrét feladatok ettől egészen eltérő szerkezeteket is igényelhetnek (pl. több hívás, ezek eredményei között műveletek)

6 Rekurzív függvény általános pszeudokódja Rekurzív feladat megoldásának lehetőségei Rekurzív specifikáció Nemrekurzív specifikáció Rekurzív algoritmus Nemrekurzív algoritmus Rekurzív programnyelv Nemrekurzív programnyelv Számítógép Az implementált programot minden esetben Neumann elvű (tehát nem rekurzív) gépen hajtjuk végre

Rekurzió Rekurzió alapjai Rekurzív algoritmusok végrehajtása Programtranszformációk

8 Verem Verem adatszerkezet Adatok tárolására szolgáló szerkezet Mindig az utoljára belehelyezett elemet (push) tudjuk belőle kiolvasni (pop) (LIFO Last In First Out) Kiolvasáskor az elem egyben törlődik is 5 4 3 7 BE 5 BE 4 BE 3 5 BE 7 KI 7 KI 3 BE 5 Később részletesebben tárgyaljuk Processzor verem A verem gyakran használt adatszerkezet az operációs rendszer, illetve a processzor működése során eljárások hívásakor a verem tárolja el a hívó utasítást követő utasítás címét (ide kell majd visszatérni a befejezés után) Szintén a veremben tárolódnak a meghívott eljárás paraméterei, lokális változói stb. Ez természetesen implementációtól függ, a mi számunkra azonban ez az egyszerűsített működési elv is megfelelő

eljárások hívásának (egy lehetséges) módja szenasi.sandor@nik.uni-obuda.hu 9... E1(1, 2)... eljárás E1(a, b) x lokális változó... E2(a+b)... eljárás E2(d) y lokális változó... C 1 2 x C 3 y verem aktuális állapota Minden függvényhíváskor eltárolódik a visszatérési cím, illetve a függvény lokális változói Visszatéréskor ezek törlődnek a veremből Ez alapján látható, hogy az általuk látott adatok szempontjából az egymás után hívott függvények valójában egymástól függetlenek Lásd változók élettartama

Rekurzív eljáráshívás szenasi.sandor@nik.uni-obuda.hu 10... függvény Fakt(a) x = Fakt(3) Ha a = 0 függvény akkor Fakt(a) a = 3... Ha a = 0 függvény akkor Fakt(a) a = 2 Fakt 1 Ha a = 0 függvény akkor Fakt(a) a = 1 különben Fakt 1 ha a = 0 akkor különben Fakt 1 (6) Fakt a * Fakt(a-1) különben (1) Fakt 1 elágazás vége (2) Fakt a * Fakt(a-1) különben függvény vége elágazás vége (1) Fakt a * Fakt(a-1) függvény vége elágazás vége Fakt a * Fakt(a-1) függvény vége elágazás vége függvény vége a = 0 x C 3.. C 2.. C 1.. C 0.. verem aktuális állapota Látható, hogy rekurzív hívás esetén is egymástól független adatokon dolgoznak az egyes függvények Az ugyanolyan nevű lokális változók emiatt nincsenek egymásra hatással Ennek figyelembevételével kell megoldanunk az egyes függvények közötti adatcserét

11 Rekurzív algoritmus bemenete Biztosítani kell, hogy minden meghívott függvény hozzáférjen a működéséhez szükséges bemenő paraméterekhez Bemenet biztosítása külső változókon keresztül Az egyes futó függvény példányok nem látják egymás lokális adatait, ezért a mindegyik számára szükséges bemeneti adatokat nem tudjuk ezek között tárolni A függvényen kívüli adatokat azonban a rekurzió minden szintjéről elérjük (globális változók, objektum adattagjai stb.) Tárhely/futásidő szempontjából optimális megoldás Bemenet biztosítása paramétereken keresztül Mint minden más függvénynél, a rekurzív függvényeknél is van lehetőség minden bemenő paramétert átadni a függvény hívásakor Ebben az esetben értelemszerűen a következő rekurzív híváskor mindezt újra át kell adni Ez jóval áttekinthetőbb, bár kevésbé hatékony megoldást nyújt

12 Rekurzív algoritmus kimenete Rekurzív hívási lánc során problémát jelenthet az eredmény visszaadás, mivel az eredeti hívó, illetve a végeredményt elérő függvény között számos függvényhívás állhat Eredmény visszaadás külső változókon keresztül A bemenethez hasonlóan itt is van arra lehetőség, hogy a végeredményig eljutó szint egy külső változóban eltárolja az eredményt, a hívó pedig majd innen kiolvassa Eredmény visszaadás függvény visszatérési értékkel Hagyományos függvényekhez hasonlóan a rekurzív függvények is rendelkezhetnek visszatérési értékkel Az önmagát meghívó függvénynek azonban biztosítania kell, hogy az (önmagától) visszakapott értéket továbbítsa a hívója felé Eredmény visszaadás paraméterekkel Amennyiben az újrahíváskor is mindig címszerinti paraméterátadás történt, akkor bármelyik szint változtatja meg a paraméter értékét, az a hívó szintjén is változni fog

13 Rekurzió jellemzői Előnyök Gyakran elegáns, jól érthető, áttekinthető kódot ad Bizonyos feladatoknál (pl. rekurzív adatszerkezetek feldolgozása esetén) jóval egyszerűbbek a rekurzív megoldások Hátrányok Gyakran áttekinthetetlen, ember számára nagyon nehezen értelmezhető kódot ad Nagyszámú újrahívás esetén a nyomkövetés nehézkes, nehezen áttekinthető A függvényhívás általában meglehetősen költséges művelet, emiatt a rekurzív algoritmusok nem hatékonyak Egy rekurzívan megadott algoritmusban gyakran észrevétlenek maradnak elhibázott döntések (bár ez nem a rekurzió, hanem a tervező hibája) Átalakítások Később látni fogjuk, hogy a rekurzív és iteratív megoldások általában egymásba alakíthatók

Rekurzió Rekurzió alapjai Rekurzív algoritmusok végrehajtása Programtranszformációk

15 Elemi konstrukciók függvények segítségével A strukturált programozásnál megismert három konstrukció egyszerűen felírható függvényekkel is Szekvencia Elágazás ciklus f(x) = g h(x) f(x) = f(x) = g(x) h(x) g(x) h f i(x) ha p(x) ha p(x) ha p(x) ha p(x) Egyszerű szabályokat követve így megadhatjuk a programozási tételek rekurzív formáját S 1 S 2 Ha L akkor S 1 különben S 2 elágazás vége ciklus amíg L S ciklus vége

16 R I Rekurzív formában megadott fv. Ha egy rekurzív függvény az alábbiak szerint számítható ki: g(f(i-1), f(i-2),..., f(i-k)) f(i) = h(i) Az iteratív megoldás: eljárás f(n) ciklus i 0-tól (K-1)-ig F[i] h[i] ciklus vége ciklus i K-tól N-ig F[i] g(f[i-1], F[i-2],..., F[i-K]) ciklus vége f F[N] ha i > K ha 0 i < K Optimálisabb változat is készíthető, hiszen a tömbből mindig csak az utolsó K elemre van szükségünk

17 R I Jobbrekurzió átírása Jobbrekurzió általános esete (a rekurzív hívást követően már nincs szükség a függvény lokális változóira): eljárás JobbRek(X, Y) Q(X, Y) ha p(x, Y) akkor S(X, Y) JobbRek(f(X), Y) elágazás vége Az iteratív megoldás: eljárás JobbRek(X, Y) Q(X, Y) ciklus amíg p(x, Y) S(X, Y) X f(x) Q(X, Y) ciklus vége

18 R I Balrekurzió átírása 1. Balrekurzió során a rekurzív függvény meghívása után is szükség van a lokális változók értékeire, azok módosulhatnak is Balrekurzió általános esete: eljárás BalRek(X, Y) ha p(x, Y) akkor BalRek(f(X), Y) S(X, Y) különben T(X, Y) elágazás vége A hívás előtt is szerepelhet valamilyen művelet, az egyszerűség kedvéért ezzel nem foglalkozunk Tipikusan akkor célszerű ezt használni, ha egy sorozatot visszafelé szeretnénk feldolgozni (verem?)

19 R I Balrekurzió átírása 2. Balrekurzió egy lehetséges iteratív átirata: eljárás BalRek(X, Y) N 0 ciklus amíg p(x, Y) Verembe(X) X f(x) N N + 1 ciklus vége T(X, Y) ciklus i 1-től N-ig Veremből(X) S(X, Y) ciklus vége Ha a sorozat elemszámát előre ismerjük, értelemszerűen nincs szükség az N számolásra Ha az f(x) függvénynek van inverze, egyszerűbb (veremnélküli) algoritmus is adható

20 Iteratív Rekurzív átalakítás Az elöl és hátultesztelős ciklusok átírása eljárás ElölTeszt(X) ciklus amíg P(X) S(X) ciklus vége eljárás HátulTeszt(X) ciklus S(X) ciklus amíg P(X) eljárás ElölTeszt(X) ha p(x) akkor S(X) ElölTeszt(X) elágazás vége eljárás HátulTeszt(X) S(X) ha p(x) akkor HátulTeszt(X) elágazás vége Számlálós ciklus egyszerűen átírható elöltesztelőssé Amennyiben a ciklus előtt vagy után további műveletek szerepelnek, azokat célszerű egy másik függvényben (a rekurzió 0. szintjén ) elvégezni

21 Irodalomjegyzék Javasolt/felhasznált irodalom Pap, Szlávi, Zsakó: μlógia4 Módszeres programozás: Rekurzió ELTE TTK, 2004 S. Harris, J. Ross: Kezdőkönyv az algoritmusokról SZAK Kiadó, 2006 Wikipedia.org megfelelő szócikkek http://en.wikipedia.org/wiki/recursion