Upload
emmett
View
34
Download
0
Embed Size (px)
DESCRIPTION
HÁZI FELADAT. HIKGHB Németh Gábor LUF9NV Simon Attila. A programozás al apjai 1. 10. előadás. Híradástechnikai Tanszék. Rekurzió. 1. 5. 2. 7. 6. 4. 3. Bináris fa bejárása - preorder (gyökér – bal gyerek – jobb gyerek) mentés - visszaállítás. 4. 6. 2. 7. 5. 3. 1. - PowerPoint PPT Presentation
Citation preview
HIKGHB Németh Gábor
LUF9NV Simon Attila
A programozás alapjai 1
10. előadás
Híradástechnikai Tanszék
Rekurzió
Bináris fa bejárása
- preorder
(gyökér – bal gyerek – jobb gyerek) mentés - visszaállítás
1
52
7643
Bináris fa bejárása
- inorder
(bal gyerek – gyökér – jobb gyerek) rendezés
4
62
7531
Bináris fa bejárása
- posztorder
(bal gyerek – jobb gyerek – gyökér) képlet kiértékelése
7
63
5421
Bináris fa bejárása
typedef … adat; typedef stuct fa {
adat a; struct fa *b,*j;
} faelem; void feldolgoz (adat d) { … }
Bináris fa bejárása
- preorder
void bejar(faelem *p) void bejar(faelem *p) { { if (p) feldolgoz(p->a); { if (p->b) bejar(p->b); feldolgoz(p->a); if (p->j) bejar(p->j); bejar(p->b); } bejar(p->j); } }
Bináris fa bejárása
- inorder
void bejar(faelem *p) void bejar(faelem *p) { { if (p) if (p->b) bejar(p->b); { feldolgoz(p->a); bejar(p->b); if (p->j) bejar(p->j); feldolgoz(p->a); } bejar(p->j); } }
Bináris fa bejárása
- posztorder
void bejar(faelem *p) void bejar(faelem *p) { { if (p) if (p->b) bejar(p->b); { if (p->j) bejar(p->j); bejar(p->b); feldolgoz(p->a); bejar(p->j); } feldolgoz(p->a); } }
Közvetlen rekurzió:
egy szegmens hivatkozik önmagára
Közvetett rekurzió:
szegmensek egymásra hivatkozásaiban kör van
A rekurzió célja:
A rekurzió célja:
A feladat méretének, vagy bonyolultságának csökkentése egy kezelhető szintig.
A rekurzió kritikus pontja:
A rekurzió kritikus pontja:
A leállás feltételének teljesülését minden esetben biztosítani kell.
A rekurzió nagy előnye
A rekurzió nagy előnyeaz elegancia
A rekurzió nagy előnyeaz elegancia
Néhány sorban,könnyen érthetőkódot írhatunk.
A rekurzió nagy hátránya
A rekurzió nagy hátrányaa csábítás
A rekurzió nagy hátrányaa csábítás
Akkor is használjuk,ha kevéssé hatékony,
sőt pazarló.
Mikor ne használjunk rekurziót?
Mikor ne használjunk rekurziót?
Ha az eredmény zárt alakban is előállítható.
Mikor ne használjunk rekurziót?
Ha az eredmény zárt alakban is előállítható. Pl.: számtani sorozat n-edik eleme
Mikor ne használjunk rekurziót?
Ha az eredmény zárt alakban is előállítható. Pl.: számtani sorozat n-edik eleme
Ha a feladat ciklusszervezéssel is könnyen megoldható.
Mikor ne használjunk rekurziót?
Ha az eredmény zárt alakban is előállítható. Pl.: számtani sorozat n-edik eleme
Ha a feladat ciklusszervezéssel is könnyen megoldható. Pl.: faktoriális számítás
A rekurzió és a ciklus kapcsolata
A rekurzió és a ciklus kapcsolata
Minden ciklus megvalósítható rekurzióval.
A rekurzió és a ciklus kapcsolata
Minden ciklus megvalósítható rekurzióval.
Minden rekurzió megvalósítható ciklussal és segédváltozókkal.
Minden ciklus megvalósítható rekurzióval.
A
C
B
Vége
A
B
C
Vége
A
Minden rekurzió megvalósítható ciklussal és segédváltozókkal.
Minden rekurzió megvalósítható ciklussal és segédváltozókkal.
A megoldásra rátalálninéha nem könnyű feladat!
Minden rekurzió megvalósítható ciklussal és segédváltozókkal.
A megoldásra rátalálninéha nem könnyű feladat!
Lássunk példát erre is, arra is!
Egy könnyű probléma:
Egy könnyű probléma:
A Fibonacci számsorozat
Egy könnyű probléma:
A Fibonacci számsorozat
1 1 2 3 5 8 13 21 34 55 …
Egy könnyű probléma:
A Fibonacci számsorozat
1 1 2 3 5 8 13 21 34 55 …
A sorozat harmadik elemétől kezdveminden elem az előző kettő összege.
A Fibonacci számsorozat
Rekurzív megvalósítás
fib(unsigned n){ if (n<2) return n; return fib(n-2) + fib(n-1);}
A Fibonacci számsorozat
Megvalósítás ciklussal
fib(unsigned n){ int regi=0,uj=1; for(n--;n;n--) { uj+=regi; regi=uj-regi;} return uj;}
Egy nehéz probléma:
Egy nehéz probléma:
Hanoi tornyai
Egy nehéz probléma:
Hanoi tornyai
A MESE
Hanoi tornyai
Rekurzív megvalósítás
void hanoi(unsigned hanyat, char honnan,char hova){char seged=3*′B′-honnan-hova;if (--hanyat) hanoi(hanyat,honnan,seged);printf(″%c %c\n″,honnan,hova);if (hanyat) hanoi(hanyat,seged,hova);}
4 A B 3 A C 2 A B 1 A C
1 A B
1 C B
1 A C
2 B C 1 B A
1 B C
1 A C
1 A B
3 C B 2 C A 1 C B
1 C A
1 B A
1 C B
2 A B 1 A C
1 A B
1 C B
Hanoi tornyai
Megvalósítás ciklussal
?
4 A B 3 A C 2 A B 1 A C
1 A B
1 C B
1 A C
2 B C 1 B A
1 B C
1 A C
1 A B
3 C B 2 C A 1 C B
1 C A
1 B A
1 C B
2 A B 1 A C
1 A B
1 C B
4 A B 3 A C 2 A B 1 A C
1 A B
1 C B
1 A C
2 B C 1 B A
1 B C
1 A C
1 A B
3 C B 2 C A 1 C B
1 C A
1 B A
1 C B
2 A B 1 A C
1 A B
1 C B
A C
A B
C B
A C
B A
B C
A C
A B
C B
C A
B A
C B
A C
A B
C B
1 A C
2 A B
3 C B
4 A C
5 B A
6 B C
7 A C
8 A B
9 C B
10 C A
11 B A
12 C B
13 A C
14 A B
15 C B
0001 A C
0010 A B
0011 C B
0100 A C
0101 B A
0110 B C
0111 A C
1000 A B
1001 C B
1010 C A
1011 B A
1100 C B
1101 A C
1110 A B
1111 C B
0001 A C 0
0010 A B 1
0011 C B 0
0100 A C 2
0101 B A 0
0110 B C 1
0111 A C 0
1000 A B 3
1001 C B 0
1010 C A 1
1011 B A 0
1100 C B 2
1101 A C 0
1110 A B 1
1111 C B 0
0001 A C 0
0010 A B 1
0011 C B 0
0100 A C 2
0101 B A 0
0110 B C 1
0111 A C 0
1000 A B 3
1001 C B 0
1010 C A 1
1011 B A 0
1100 C B 2
1101 A C 0
1110 A B 1
1111 C B 0
0001 A C 0
0010 A B 1
0011 C B 0
0100 A C 2
0101 B A 0
0110 B C 1
0111 A C 0
1000 A B 3
1001 C B 0
1010 C A 1
1011 B A 0
1100 C B 2
1101 A C 0
1110 A B 1
1111 C B 0
0001 A C 0
0010 A B 1
0011 C B 0
0100 A C 2
0101 B A 0
0110 B C 1
0111 A C 0
1000 A B 3
1001 C B 0
1010 C A 1
1011 B A 0
1100 C B 2
1101 A C 0
1110 A B 1
1111 C B 0
0001 A C 0
0010 A B 1
0011 C B 0
0100 A C 2
0101 B A 0
0110 B C 1
0111 A C 0
1000 A B 3
1001 C B 0
1010 C A 1
1011 B A 0
1100 C B 2
1101 A C 0
1110 A B 1
1111 C B 0
0001 A C 0
0010 A B 1
0011 C B 0
0100 A C 2
0101 B A 0
0110 B C 1
0111 A C 0
1000 A B 3
1001 C B 0
1010 C A 1
1011 B A 0
1100 C B 2
1101 A C 0
1110 A B 1
1111 C B 0
A páratlan lépéseket a legkisebb koronggal tesszük meg, mindig ugyanarra.
A párosadik lépések is egyértelműen meghatározottak:
- Tudjuk, hogy merre kell lépni.- Amivel léptünk, azzal nem léphetünk.- A legkisebb korongra nem rakodhatunk.
Hanoi tornyai
Megvalósítás ciklussal
- Ha n korong van, 2n-1 lépés kell.- Minden páratlanadik lépést a legkisebb koronggal kell megtenni.- Ha n páratlan, A-B-C-A sorrendben lép, ha n páros, A-C-B-A sorrendben lép.- Ha a következő lépést ugyanarra kell megtenni, oda kell lépni, ahonnan léptünk.- Ha a következő lépést ellenkező irányban kell megtenni, onnan kell lépni, ahonnan léptünk.
Hogyan lehet megvalósítania rekurziót?
Hogyan lehet megvalósítani,hogy a függvénynek egyszerre
több példánya éljen?
Ezt már tudjuk!
A nagy ÖTLET: CSAK EGY VEREM KELL!
Kalkulátor verem = ahol a kifejezések kiértékelése történik
Hívás verem = ahol a visszatérési címet tároljuk
Paraméter verem = ahol a paramétereket adjuk át
Ha már lúd, legyen kövér!Tároljuk itt a szegmensek belső változóit is!
Mit kell tudnia a függvényről a fordítóprogramnak,
hogy meg tudja hívni?
azonosítójáta megvalósító szubrutin címét
paraméterezésétaz átadandó paraméterek típusát
Ez képezi a függvény deklarációját
Mit nem szükséges tudniaa függvényről
a fordítóprogramnak, hogy meg tudja hívni?
megvalósításátaz végrehajtandó utasításokat
Ez képezi a függvény definícióját
Hogyan definiálunk függvényt?
Ezt is tudjuk!
Függvény definíciója
<visszatérési érték típusa><függvény azonosítója> (<formális paraméterek listája>)<blokk>
A közvetlen rekurzióhoz ez több mint elég!
Közvetlen rekurzió:
egy szegmens hivatkozik önmagára
De mi a helyzet a közvetett rekurzióval?
Közvetett rekurzió:
szegmensek egymásra hivatkozásaiban kör van
Ez a„tyúk vagy a tojás”
esete!
Megoldás:
Válasszuk szét a függvénydeklarációját
ésdefinícióját!
Függvény definíciója
<visszatérési érték típusa><függvény azonosítója> (<formális paraméterek listája>)<blokk>
Függvény deklarációja
<visszatérési érték típusa><függvény azonosítója> (<paraméterek listája>);
Függvény deklarációja
<visszatérési érték típusa><függvény azonosítója> (<paraméterek listája>);
A blokk helyén ; áll.
Függvény deklarációja
<visszatérési érték típusa><függvény azonosítója> (<paraméterek listája>);
A paraméterek nevét a fordítóprogram nem veszi figyelembe, ezért elhagyható, vagy tetszőleges nevet használhatunk.
A függvény deklarációjaminden a híváshoz szükséges
információt tartalmaz.
A függvény prototípusánakis nevezzük.
Másként a függvény fejléce.
A függvények tetszőleges sorrendben hívhatják egymást,
ha a fejléceket kigyűjtjük,és a kód elejére írjuk.
Jó szokás egy fájlba írni,és #include direktívával
hivatkozni rá.