You are on page 1of 41

Rekurzi

(Horvth Gyula s Szlvi Pter eladsai


felhasznlsval)

Klasszikus pldk
Faktorilis

n * n 1 ! ha n 0
ha n 0
1

n!

Fibonacci-szmok
0
ha n 0
Fib n 1
ha n 1
Fib n 1 Fib n 2 ha n 1

A rekurzi lnyege: nhivatkozs

Rekurzi

Klasszikus pldk
Binomilis szmok:

1
ha k 0
B n, k B n 1, k B n 1, k 1 ha 0 k n
1
ha k n

Rekurzi
6/14/15

Rekurzv specifikci s algoritmus


Faktorilis:

n * n 1 ! ha n 0
n!
ha n 0
1

int Faktorialis(int n)
{
if(n>0)
return n * Faktorialis(n-1);
else
return 1;
}

Rekurzi
6/14/15

Fibonacci szmok:
0
ha n 0
Fib n 1
ha n 1
Fib n 1 Fib n 2 ha n 1
int Fib(int n)
{
if(n==0)
return 0;
else if(n==1)
return 1;
else
return Fib(n-1)+Fib(n-2);
}

Rekurzi
6/14/15

Binomilis szmok:
1
ha k 0
B n, k B n 1, k B n 1, k 1 ha 0 k n
1
ha k n

int Binom(int n, int k)


{
if(k==0 || k==n)
return 1;
else
return Binom(n-1,k)+Binom(n-1,k-1);
}
Rekurzi
6/14/15

Rekurzv eljrs
Feladat:
Egy kp egy adott (fehr szn) tartomnyt egy
(A,B) bels pontjbl kiindulva fessk be
vilgoskkre!

Festendk a bels pontok, azaz


Bels(i,j)=(i=A s j=B) vagy
Fehr(i,j) s (Bels(i1,j) vagy Bels(i+1,j)
vagy
Bels(i,j1) vagy Bels(i,j+1))
Rekurzi

Rekurzv eljrs
Rekurzv fests pontonknt:
RekPont(x,y):
Fest(x,y)
Ha res(x-1,y)
Ha res(x,y-1)
Ha res(x+1,y)
Ha res(x,y+1)
Eljrs vge.

Rekurzi
6/14/15

akkor
akkor
akkor
akkor

RekPont(x-1,y)
RekPont(x,y-1)
RekPont(x+1,y)
RekPont(x,y+1)

Rekurzi Logo nyelven


Koch fraktl:
Vegynk egy egysgnyi szakaszt!
Vgjuk ki a kzps harmadt!
Illesszk be a kivgott rszt egy egyenl
oldal hromszg oldalaiknt!
Alkalmazzuk ugyanezt az gy kapott 4
szakaszra!

Rekurzi
6/14/15

Rekurzi Logo nyelven


Koch fraktl, Logo megolds:
Tanuld koch :n :h
Ha :n=0 [elre :h]
[koch :n-1 :h/3 balra 60
koch :n-1 :h/3 jobbra 120
koch :n-1 :h/3 balra 60
koch :n-1 :h/3]
Vge

Rekurzi
6/14/15

koch 1 100

10

koch 2 100

Rekurzv eljrs
Hanoi tornyai:
Adott 3 rudacska. Az elsn egyre cskken
sugar korongok vannak. Az a feladat, hogy
tegyk t a harmadik rudacskra a korongokat
egyenknt gy, hogy az tpakols kzben s
termszetesen a vgn is minden egyes
korongon csak nla kisebb lehet. Az
tpakolshoz lehet segtsgl felhasznlni a
kzps rudacs-kt.

Rekurzi
6/14/15

11

Hanoi tornyai:

Rekurzi
6/14/15

12

void trak(int korong, char honnan, char hova)


{
cout<<korong<<" "<<honnan<<" -> "<<hova<<endl;
}
//a: honnan, b: hova, c: segtsgvel
void Hanoi(int n, char a, char b, char c)
{
if(n>0)
{
Hanoi(n-1,a,c,b);
trak(n,a,b);
Hanoi(n-1,c,b,a);
}
}
Rekurzi
6/14/15

13

A megvalsts
problmi
sszefoglalva a problmkat:
1. A bemen paramter problematikja.
Hogyan kerl a bemen rtk ugyanazzal a
kddal megvalstott eljrshoz, azaz a
rekurzvan jbl a hvotthoz?

2. A fggvnyeljrsok rtkvisszaadsa.
Hogyan kerl a (rekurzvan) hvott fggvny
rtke a hv eljrsban felsznre?

3. A loklis vltozk egyedisge.


Rekurzi
6/14/15

14

A megvalsts
problmi
A megolds vzlata:
1. s 3. problma belpskor vermels,
kilpskor verembl kivtel.
2. problma (nem csak rekurzinl) az rtk
verembe ttele kzvetlenl a visszatrs eltt.
A fggvnyt eljrss alaktva:
Fakt(n):
Verembe(n)
Ha n=0 akkor f:=1
klnben Fakt(n-1); Verembl(f)
n:=Veremtet; f:=n*f
Verembl(n); Verembe(f)
Eljrs vge.
Rekurzi
6/14/15

15

Problmk a
rekurzival
Bajok a rekurzival
Hely: nagyra dagadt veremmret.
Id:
o a vermels adminisztrcis tbbletterhe
o a tbbszrsen ismtld hvsok.

Rekurzi

16

Oszd meg s
uralkodj!
Oszd meg s uralkodj!
Tbb rszfeladatra bonts, amelyek hasonlan
oldhatk meg, lpsei:
a trivilis eset (amikor nincs rekurzv
hvs)
feloszts (megadjuk a rszfeladatokat,
amikre a feladat lebonthat)
uralkods (rekurzvan megoldjuk az egyes
rszfeladatokat)
sszevons (az egyes rszfeladatok
megoldsbl
ellltjuk az eredeti feladat
Rekurzi
17

Ezek alapjn a kvetkezkppen fogunk


gondolkodni:
Mi az ltalnos feladat alakja? Mik a
paramterei? Ebbl kapjuk meg a rekurzv
eljrsunk specifikcijt.
Milyen paramterrtkekre kapjuk a konkrt
feladatot? Ezekre fogjuk meghvni kezdetben az
eljrst!
Mi a lells (trivilis eset) felttele? Hogyan
oldhat meg ilyenkor a feladat?
Hogyan vezethet vissza a feladat hasonl, de
egyszerbb rszfeladatokra? Hny rszfeladatra
vezethet vissza?

Melyek
ilyenkor
az
ltalnos
feladat
Rekurzi
18

Gyorsrendezs
(quicksort)!
Felbonts:

az els elemet tegyk a helyre


(k), azaz eltte nincs nagyobb, utna nincs
kisebb
X1, ... , Xk-1 Xk Xk+1, ... , Xn
helyben
sztvlogats
Uralkods: mindkt rszt ugyanazzal a
mdszerrel felbontjuk kt rszre, rekurzvan
sszevons: automatikusan trtnik a
helyben sztvlogats miatt
Trivilis eset: n1
Rekurzi

19

Gyorsrendezs
(quicksort)!
void quicksort(int e, int u)
{
if(e<u)
{
int k = helyrevisz(e, u);
quicksort(e, k-1);
quicksort(k+1, u);
}
}
int main()
{
quicksort(0,n-1);
}
Rekurzi

20

Gyorsrendezs
(quicksort)!

Az els elemet a helyre viszi (helyben sztvlogats):


int helyrevisz(int e, int u)
{
int tmp = x[e];
while(e<u)
{
while(e<u && x[u]>=tmp)
--u;
x[e]=x[u];
while(e<u && x[e]<=tmp)
++e;
x[u]=x[e];
}
x[e]=tmp;
return e;
}

Rekurzi
6/14/15

21

sszefuttatsos rendezs
(mergesort)!
felbonts:

a sorozat kt rszsorozatra bontsa

(kzpen)
X1, ... , Xk Xk+1, ... , Xn
uralkods:

a kt rszsorozat rendezse
(rekurzvan)
sszevons: a kt rendezett rszsorozat
sszefslse
trivilis eset: n1
Rekurzi

22

sszefuttatsos rendezs
(mergesort)!
void mergesort(int e, int u)
{
if(e<u)
{
int k = (e+u)/2;
mergesort(e, k);
mergesort(k+1, u);
merge(e, k, u);
}
}
Rekurzi

23

sszefuttatsos rendezs
(mergesort)!
lemsoljuk az x tmbt tmp-be, majd innen futtatjuk ssze x-be
int merge(int e, int k, int u)
{
int tmp[n];
for(int i=e; i<=u; ++i)
tmp[i]=x[i];
int i = e, j = k+1;
int db = 0;
while(i<=k && j<=u)
{
if(tmp[i]<tmp[j])
x[e+db++] = tmp[i++];
else
x[e+db++] = tmp[j++];
}
while(i<=k)
x[e+db++] = tmp[i++];
while(j<=u)
x[e+db++] = tmp[j++];
}
Rekurzi

24

i-edik legkisebb
kivlasztsa
Felbonts:

az els elemet tegyk a helyre


(K), azaz eltte nincs nagyobb, utna nincs
kisebb
X1, ... , Xk-1 Xk Xk+1, ... , Xn
helyben
sztvlogats
uralkods: i<K esetn az els, i>K esetn a
msodik rszben keresnk tovbb, rekurzvan
sszevons: automatikusan trtnik a helyben
sztvlogats miatt
trivilis eset: i=k
Rekurzi

25

i-edik legkisebb
kivlasztsa
int kivalaszt(int e, int u, int i)
{
int k = helyrevisz(e, u);
if(i==k)
return k;
else if(i<k)
return kivalaszt(e, k-1, i);
else
return kivalaszt(k+1, u, i);
}
Elfelt: 0<=i<n

Rekurzi

26

N szm legnagyobb kzs osztja

Rekurzi

A sorozatot bontsuk kt rszre; mindkt rsznek


hatrozzuk meg a legnagyobb kzs osztjt,
majd ezek legnagyobb kzs osztja lesz a
megolds. Ehhez a legnagyobb kzs oszt
albbi tulajdonsgt hasznljuk ki:
lnko(X1, ... Xk, Xk+1, ... , Xn) =
lnko( lnko(X1, ... Xk) , lnko(Xk+1, ... , Xn) )

27

N szm legnagyobb kzs osztja

Rekurzi

lellsi felttel: az ppen vizsglt sorozatnak


1 eleme van: a legnagyobb kzs oszt
nmaga
felbonts: a sorozat kt rszsorozatra bontsa
(kzpen)
X1, ... , Xk, Xk+1, ... , Xn
uralkods: mindkt rszsorozatra
meghatrozzuk a legnagyobb kzs osztt
(rekurzvan)
sszevons: a kt legnagyobb kzs osztnak
vesszk a legnagyobb kzs osztjt.
28

N szm legnagyobb kzs osztja


Gyorstsi lehetsgek:
ha az els rsz legnagyobb kzs osztja 1,
akkor a msodik rszt mr ki sem kell
szmolni, az eredmny 1;
ha a msodik rsz legnagyobb kzs osztja
1, akkor a kt rsz legnagyobb kzs osztja
is biztosan 1.

Rekurzi

29

//euklideszi algoritmus
int lnko(int a, int b)
{
if(a%b==0)
return b;
else
return lnko(b,a%b);
}
int lnkoN(int e, int u)
{
if(e==u)
return x[e];
else
{
int k = (e+u)/2;
int L1 = lnkoN(e,k);
int L2 = 1;
if(L1>1)
{
L2 = lnkoN(k+1,u);
}
return lnko(L1,L2);
}
}
Rekurzi

30

Jrdakvezs
Feladat
Szmtsuk ki, hogy hnyflekppen lehet egy n
egysg mret jrdt kikvezni 1x1, 1x2 s
1x3 mret lapokkal!
Az els helyre tehetnk 1x1-es lapot:
Az els helyre tehetnk 1x2-es lapot:
Az els helyre tehetnk 1x3-as lapot:

Rekurzi

Az els esetben n-1, a msodikban n-2-t, a


harmadikban pedig n-3 cellt kell mg
lefednnk. Azaz az n cella lefedseinek
31
Lefed(n) szma:

Jrdakvezs
int Lefed(int n)
{
if(n==0)
return 0;
else if(n==1)
return 1;
else if(n==2)
return 2;
else
return Lefed(n-1)+Lefed(n-2)+Lefed(n-3);
}

Rekurzi
6/14/15

32

Kzvetett rekurzi jrdakvezs


Feladat
Szmtsuk ki, hogy hnyflekppen lehet egy
2xn egysg mret jrdt kikvezni 1x2 s
1x3 mret lapokkal!

Megolds
Biztos nincs megolds, ha n<2!

Rekurzi

33

Kzvetett rekurzi jrdakvezs


Az els oszlop egyflekppen fedhet le:
Az els kt oszlop tovbbi elrendezssel jra
egyflekppen fedhet le:
Az els hrom oszlop jra egyflekppen:
Sajnos ez is elfordulhat:
Rekurzi

34

Kzvetett rekurzi jrdakvezs

Jellje A(n) a megolds rtkt 2xn egysg


mret jrda esetn!
Jellje B(n) a megolds rtkt 2xn egysg
mret jrda esetn, ha az egyik jobboldali
1
ha n 1
sarok nincs befestve!
2
ha n 2

A n
4

A n 1 A n 2 A n 3 2 B n 2

B n

Rekurzi

0
0
1
A n 3 B n 1 B n 3
35

ha
ha
ha
ha

ha

n 3

ha

n 3

n 1
n2
n 3
n 3

int B(int n);


int A(int n)
{
if(n==1)
return 1;
else if(n==2)
return 2;
else if(n==3)
return 4;
else
return A(n-1)+A(n-2)+A(n-3)+2*B(n-2);
}
int B(int n)
{
if(n==1)
return 0;
else if(n==2)
return 0;
else if(n==3)
return 1;
else
return A(n-3)+B(n-1)+B(n-3);
}

Kzvetett rekurzi jrdakvezs


Feladat
Szmtsuk ki, hogy hnyflekppen lehet egy
3xn egysg mret jrdt kikvezni 1x2
mret lapokkal!

Megolds
Biztos nincs megolds, ha n pratlan szm!

Rekurzi

37

Kzvetett rekurzi jrdakvezs


Az els oszlop kzps ngyzete hromflekppen
fedhet le.

1. eset

2.
eset

3. eset
Rekurzi

38

Kzvetett rekurzi jrdakvezs

Az egyes esetek csak az albbi mdon


folytathatk:
Jellje A(n) a megolds rtkt 3xn egysg
mret jrda esetn!

Az 1. eset csak gy folytathat

Rekurzi

39

Kzvetett rekurzi jrdakvezs

Jellje B(n) azt, hogy hnyflekppen fedhet le


egy 3xn egysg mret jrda, amelynek a bal
als sarka mr le van fedve!
Szimmetria miatt a jobb fels sarok
lefedettsge esetn is B(n)-fle lefeds van.

A 2. eset csak
gy folytathat
0
ha nA 13. eset csak gy

folytathat
A n
3
ha n 2
A n 2 2 B n 1

Rekurzi

40

ha n 2

Kzvetett rekurzi jrdakvezs


Az egyes esetek csak az albbi mdon
folytathatk:
Jellje B(n) azt, hogy hnyflekppen fedhet le
egy 3xn egysg mret jrda, amelynek a bal
als sarka mr le van fedve! B(n) pros n-re
mindig 0 rtk!

1
ha n 1

B n
Egy csempe s0A(n-1) ha n 2Kt csempe s B(n-2)
A n 1 B n 2 ha n 2

Rekurzi

41

You might also like