Rekurzív algoritmusok 11. előadás Sergyán Szabolcs sergyan.szabolcs@nik.uni-obuda.hu Óbudai Egyetem Neumann János Informatikai Kar 2011. november 14. Sergyán (OE NIK) AAO 11 2011. november 14. 1 / 32
Rekurzív algoritmusok 1 Faktoriális 2 Fibonacci számok 3 Binomiális együtthatók 4 Ackermann függvény 5 Egyszerű feladatok 6 Keresések 7 Rekurzív rendezés 8 Hanoi tornyai Sergyán (OE NIK) AAO 11 2011. november 14. 2 / 32
Faktoriális Matematikai definíció Az n N faktoriálisa (jelölés: n!) alatt az első n darab pozitív természetes szám szorzatát értjük, n = 0 esetén pedig 1-et. 1, ha n = 0, n! = n i, ha n 1. i=1 Megvalósítás az Összegzés tétellel fakt(n, R) R := 1 Ciklus i := 1-től N-ig R := R i Ciklus vége Eljárás vége Sergyán (OE NIK) AAO 11 2011. november 14. 3 / 32
Rekurzív faktoriális Matematikai definíció A faktoriális rekurzív módon is definiálható: { 1, ha n = 0, n! = n (n 1)!, ha n 1. Függvénnyel leírva fakt(n) = { 1, ha n = 0, n fakt(n 1), ha n 1. Összetevők A rekurzív definíciónak két része van: Alapeset (itt most az n = 0 eset) Indukciós lépés: visszavezetjük a problémát kisebb számok esetére. Sergyán (OE NIK) AAO 11 2011. november 14. 4 / 32
Rekurzív faktoriális Rekurzív algoritmus fakt(n) Ha N = 0, akkor return(1) return(n fakt(n 1)) Függvény vége Kiértékelés fakt(5) = 5 fakt(4) 5 4 fakt(3) 5 4 3 fakt(2) 5 4 3 2 fakt(1) 5 4 3 2 1 fakt(0) 5 4 3 2 1 1 5 4 3 2 1 5 4 3 2 5 4 6 5 24 120 Sergyán (OE NIK) AAO 11 2011. november 14. 5 / 32
Rekurzió megvalósítása Problémák Ugyanabból a függvényből egyszerre több is fut? Előző példában a fakt függvényből egyszerre 6 is futott. A függvényen belüli lokális változók értéke felüĺıródik? Előző példában honnan lehet tudni, hogy N értéke éppen mennyi? Megoldás Minden meghívott függvény más, csak a nevük azonos. A memóriában eltároljuk, hogy honnan hívtunk egy függvény, majd ide lehet visszatérni később. A lokális változók minden egyes függvényben külön-külön létrejönnek. Azonos nevű, de különböző változókról van szó, hiszen a függvények is különbözőek. Az ezen célra fenntartott memória túlcsordúlhat túl sok függvényhívás esetén. Sergyán (OE NIK) AAO 11 2011. november 14. 6 / 32
Rekurzió megvalósítása R :=fakt(5) Ha 5 = 0, akkor... R := 5 fakt(4) Függvény vége R :=fakt(4) Ha 4 = 0, akkor... R := 4 fakt(3) Függvény vége R :=fakt(3) Ha 3 = 0, akkor... R := 3 fakt(2) Függvény vége R :=fakt(0) Ha 0 = 0, akkor R := 1... Függvény vége R :=fakt(1) Ha 1 = 0, akkor... R := 1 fakt(0) Függvény vége R :=fakt(2) Ha 2 = 0, akkor... R := 2 fakt(1) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 7 / 32
Rekurzív algoritmusok 1 Faktoriális 2 Fibonacci számok 3 Binomiális együtthatók 4 Ackermann függvény 5 Egyszerű feladatok 6 Keresések 7 Rekurzív rendezés 8 Hanoi tornyai Sergyán (OE NIK) AAO 11 2011. november 14. 8 / 32
Fibonacci számok Nyulak szaporodásának vizsgálata Fibonacci a nyulak szaporodását vizsgálta, és a következőket tapasztalta: Minden nyúlpár - amikor szaporodik -, akkor két utóddal járul hozzá a népességhez. A nyulak a születésüket követően két egymás utáni időpontban szaporodnak. Vizsgáljuk, hogy adott időpontban hány új nyúlpár születik. Matematikai leírás Jelölje Fib(n), hogy az n-edik szaporodáskor hány új nyúlpár születik. Kezdetben van egy nyúlpár: Fib(0) = 1 Következő szaporodáskor ez a pár szaporodik: Fib(1) = 1 Minden más szaporodáskor az előző és az azt megelőző szaporodáskor született nyulak járulnak hozzá a szaporodáshoz (mégpedig egy-egy nyúlpárral). Tehát: Fib(n) = Fib(n 1) + Fib(n 2) Sergyán (OE NIK) AAO 11 2011. november 14. 9 / 32
Fibonacci számok Rekurzív algoritmus Fib(N) Ha N 1 akkor return(1) return(fib(n 1) + Fib(N 2)) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 10 / 32
Fibonacci számok Az algoritmus megvalósítható rekurzió nélkül is. Iteratív algoritmus Fib(N) a := 1 e := 1 Ciklus i := 1-től N 1-ig temp := a + e e := a a := temp Ciklus vége return(a) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 11 / 32
Rekurzív algoritmusok 1 Faktoriális 2 Fibonacci számok 3 Binomiális együtthatók 4 Ackermann függvény 5 Egyszerű feladatok 6 Keresések 7 Rekurzív rendezés 8 Hanoi tornyai Sergyán (OE NIK) AAO 11 2011. november 14. 12 / 32
Binomális együtthatók Matematikai definíció ( ) n = k Algoritmus 1, ( ha k = 0 n 1 ) ( k + n 1 k 1), ha 0 < k < n 1, ha k = n Bin(N, K) Ha (K = 0) vagy (K = N) akkor return(1) return(bin(n 1, K) + Bin(N 1, K 1)) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 13 / 32
Rekurzív algoritmusok 1 Faktoriális 2 Fibonacci számok 3 Binomiális együtthatók 4 Ackermann függvény 5 Egyszerű feladatok 6 Keresések 7 Rekurzív rendezés 8 Hanoi tornyai Sergyán (OE NIK) AAO 11 2011. november 14. 14 / 32
Ackermann függvény Matematikai definíció n + 1, ha m = 0, A(m, n) = A(m 1, 1), ha m > 0 és n = 0, A (m 1, A(m, n 1)), ha m > 0 és n > 0. Algoritmus Ackermann(M, N) Ha M = 0 akkor return(n + 1) Ha (M > 0) és (N = 0) akkor return(ackermann(m 1, 1)) return(ackermann(m 1, Ackermann(M, N 1))) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 15 / 32
Rekurzív algoritmusok 1 Faktoriális 2 Fibonacci számok 3 Binomiális együtthatók 4 Ackermann függvény 5 Egyszerű feladatok 6 Keresések 7 Rekurzív rendezés 8 Hanoi tornyai Sergyán (OE NIK) AAO 11 2011. november 14. 16 / 32
Szöveg megfordítása Feladat Az X változóban adott egy N hosszúságú szöveg. Feladat, hogy a karakterek sorrendjét megfordítsuk. Például: abcdef fedcba Rekurzív megvalósítás Fordítás(X, N) Ha N = 1 akkor return(x ) különben return(fordítás(x [2..N], N 1) + X [1]) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 17 / 32
Palindrom Feladat Egy N-jegyű szám palindrom, ha az i-edik számjegye megegyezik az (N + 1 i)-edik számjegyével. Például: 9876543456789. Egy szám számjegyeit tároljuk az N elemű X tömbben. Egy egyjegyű szám palindrom. Ha a két szélső számjegy azonos, akkor vizsgáljuk a szélsők nélküli számot. Sergyán (OE NIK) AAO 11 2011. november 14. 18 / 32
Palindrom Rekurzív megvalósítás Palindrom e(x, N) Ha N <= 1 akkor return(igaz) Ha X [1] = X [N] akkor return(palindrom e(x [2..N 1], N 2)) return(hamis) Eljárás vége Sergyán (OE NIK) AAO 11 2011. november 14. 19 / 32
Hatványozás Az a pozitív egész szám n-edik hatványát kiszámíthatjuk az alábbi módon: Algoritmus Hatvány(a, n) temp := 1 Ciklus i := 1-től n-ig temp := temp a Ciklus vége return(temp) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 20 / 32
Hatványozás Ötlet { a n a n/2 a = n/2, ha n páros a (n 1)/2 a (n 1)/2 a, ha n páratlan Rekurzív megvalósítás Hatvány(a, n) Ha n = 0 akkor return(1) Ha n páros, akkor return(hatvány(a, n/2)*hatvány(a, n/2)) return(hatvány(a, (n 1)/2)*Hatvány(a, (n 1)/2)*a) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 21 / 32
Rekurzív algoritmusok 1 Faktoriális 2 Fibonacci számok 3 Binomiális együtthatók 4 Ackermann függvény 5 Egyszerű feladatok 6 Keresések 7 Rekurzív rendezés 8 Hanoi tornyai Sergyán (OE NIK) AAO 11 2011. november 14. 22 / 32
Lineáris keresés Ötlet a rekurzív megvalósításhoz Tegyük fel, hogy nem rendezett a sorozatunk Ha az X sorozat első eleme nem egyezik meg a keresett Y -nal, akkor hívjuk meg ismét a függvényt, de már csak a másodiktól az N-edik elemig terjedő részsorozattal. E jelölje a vizsgálandó részsorozat első elemének indexét, U pedig az utolsó elem indexét A függvény visszatérési értéke legyen 0, ha Y nincs benne X -ben, egyéb esetben pedig az X -beli indexe annak az elemnek, amely értéke egyenlő Y -nal Sergyán (OE NIK) AAO 11 2011. november 14. 23 / 32
Lineáris keresés Rekurzív megvalósítás Keresés(X, E, U, Y ) Ha E > U akkor return(0) Ha X [E] = Y akkor return(e) return(keresés(x, E + 1, U, Y )) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 24 / 32
Logaritmikus keresés Ebben az esetben tegyük fel, hogy növekvő módon rendezett a sorozatunk. Rekurzív megvalósítás Keresés(X, E, U, Y ) Ha E > U akkor return(0) [ ] K := (E + U)/2 Elágazás X [K] = Y esetén return(k) X [K] < Y esetén return(keresés(x, K + 1, U, Y )) X [K] > Y esetén return(keresés(x, E, K 1, Y )) Függvény vége Sergyán (OE NIK) AAO 11 2011. november 14. 25 / 32
Rekurzív algoritmusok 1 Faktoriális 2 Fibonacci számok 3 Binomiális együtthatók 4 Ackermann függvény 5 Egyszerű feladatok 6 Keresések 7 Rekurzív rendezés 8 Hanoi tornyai Sergyán (OE NIK) AAO 11 2011. november 14. 26 / 32
Quicksort Alapötlet Válogassuk szét úgy a rendezendő X tömb elemeit, hogy az első elemnél kisebb értékű elemek az első elem elé, a nagyobbak pedig mögé kerüljenek. Végezzük el ezt a szétválogatást az első elemnél kisebbekre, illetve nagyobbakra külön-külön. Ez az eljárás az Oszd meg és uralkodj! elvet használja. Sergyán (OE NIK) AAO 11 2011. november 14. 27 / 32
Quicksort Szétválogató eljárás Szétválogat(X, E, U, K) K := E; L := U; A := X [K] Ciklus amíg K < L Ciklus amíg (K < L) és (X [L] A) L := L 1 Ciklus vége Ha K < L akkor X [K] := X [L]; K := K + 1 Ciklus amíg (K < L) és (X [K] A) K := K + 1 Ciklus vége Ha K < L akkor X [L] := X [K]; L := L 1 Ciklus vége X [K] := A Eljárás vége Sergyán (OE NIK) AAO 11 2011. november 14. 28 / 32
Quicksort Rekurzív hívás Quick(X, E, U) Szétválogat(X, E, U, K) Ha K E > 1 akkor Quick(X, E, K 1) Ha U K > 1 akkor Quick(X, K + 1, U) Eljárás vége Sergyán (OE NIK) AAO 11 2011. november 14. 29 / 32
Rekurzív algoritmusok 1 Faktoriális 2 Fibonacci számok 3 Binomiális együtthatók 4 Ackermann függvény 5 Egyszerű feladatok 6 Keresések 7 Rekurzív rendezés 8 Hanoi tornyai Sergyán (OE NIK) AAO 11 2011. november 14. 30 / 32
Hanoi tornyai Feladat Az egyik szélső rúdról át kell pakolni a korongokat a másik szélső rúdra. Segítségül a középső rúd is használható. Egyszerre egyetlen korong mozgatható. Csak felül lévő korongot lehet mozgatni egyik rúdról a másikra. Egy korong nem rakható nála kisebb méretű korongra. Sergyán (OE NIK) AAO 11 2011. november 14. 31 / 32
Hanoi tornyai Megoldási ötlet Ha N 1 korongot át tudnánk mozgatni a középső rúdra, akkor az N-edik korong ezután már áttehető a jobbszélső rúdra, majd a középső rúdról kell az N 1 korongot a jobbszélsőre tenni. Ez egy rekurzív gondolat! A rekurzió biztos leáll, mert a legkisebb korong mindig felül van, és bárhonnan bárhova mozgatható. Algoritmus Hanoi(N, Forras, Cel, Seged) Ha N > 0 akkor Hanoi(N 1, Forras, Seged, Cel) Ki: N, Forras, Cel Hanoi(N 1, Seged, Cel, Forras) Eljárás vége Sergyán (OE NIK) AAO 11 2011. november 14. 32 / 32