If you can't read please download the document
Upload
nguyenhuong
View
219
Download
3
Embed Size (px)
Citation preview
12. Rekursion
Prof. Dr. Bernhard Humm
FH Darmstadt, 24. Januar 2006
Grundlagen der
Programmierung 1 (Java)
Fachhochschule Darmstadt
Haardtring 100
D-64295 Darmstadt
Seite 224.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Einordnung im Kontext der Vorlesung
1. Einfhrung
2. Einfache Programme
3. Kontrollstrukturen
4. Objekt-Orientierung I
5. Algorithmen und Datenstrukturen I
6. Interfaces
8. Parametrisierte Typen (Generics)
7. Pakete
12. Rekursion
9. Fehler und Ausnahmen
13. Algorithmen und Datenstrukturen II
14. Objektorientierung II
11. Komponenten
15. Design
16. Die Java Klassenbibliothek I
17. Die Java Klassenbibliothek II
10. Gutes Programmieren
Definition
Beispiele
Eigenschaften rekursiver Algorithmen
Seite 324.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Definition
Agenda
Seite 424.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Definition von Rekursion
Beispiel: Fakultt
Eine Methode m() heit rekursiv, wenn sie sich selbst aufruft
m() m() direkt rekursiv
m() n() m() indirekt rekursiv
Beispiel: Berechnung der Fakultt (n!)
n! = 1 * 2 * 3 * ... * (n-1) * n
(n-1)!
rekursive Definition
n! = (n-1)! * n
1! = 1
Rekursive Methode zur Berechnung der Fakultt
long fact (long n) {
if (n == 1)
return 1;
else
return fact(n-1) * n;
}
Allgemeines Muster
if (Problem klein genug)
nichtrekursiver Zweig;
else
rekursiver Zweig
Seite 524.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Ablauf einer rekursiven Methode
Beispiel: Fakultt
long fact (long n) {if (n == 1) return 1else return fact(n-1) * n;
}
n = 4Jede Aktivierung von fact hat ihr eigenes n
und rettet es ber den rekursiven Aufruf hinweg
long fact (long n) {if (n == 1) return 1else return fact(n-1) * n;
}
n = 3
long fact (long n) {if (n == 1) return 1else return fact(n-1) * n;
}
n = 2
long fact (long n) {if (n == 1) return 1else return fact(n-1) * n;
}
n = 1 1
6
24
2
Definition
Beispiele
Eigenschaften rekursiver Algorithmen
Seite 624.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Beispiele
Agenda
Seite 724.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Beispiel: binres Suchen rekursiv
z.B. Suche von 17 (Array muss sortiert sein)
2
0
3
1
5
2
7
3
11
4
13
5
17
6
19
7
low m high
a Index m des mittleren Element bestimmen
17 > a[m] in rechter Hlfte weitersuchen
2
0
3
1
5
2
7
3
11
4
13
5
17
6
19
7
low m high
a
static int search (int elem, int[] a, int low, int high) {
if (low > high) return -1; // empty
int m = (low + high) / 2;
if (elem == a[m]) return m;
if (elem < a[m]) return search(elem, a, low, m-1);
return search(elem, a, m+1, high);
}
nichtrekursiver Zweig
rekursiver Zweig
Seite 824.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
2 3 5 7 11 13 17 19
Ablauf des rekursiven binren Suchens
static int search (int elem, int[] a, int low, int high) {if (low > high) return -1;int m = (low + high) / 2;if (elem == a[m]) return m;if (elem < a[m]) return search(elem, a, low, m-1);return search(elem, a, m+1, high);
}
low high
0 1 2 3 4 5 6 7
m
6
elem = 17, low = 0, high = 7 6
m = 3
static int search (int elem, int[] a, int low, int high) {if (low > high) return -1;int m = (low + high) / 2;if (elem == a[m]) return m;if (elem < a[m]) return search(elem, a, low, m-1);return search(elem, a, m+1, high);
}
2 3 5 7 11 13 17 19
low high
0 1 2 3 4 5 6 7
m
low = 4, high = 7
m = 5
static int search (int elem, int[] a, int low, int high) {if (low > high) return -1;int m = (low + high) / 2;if (elem == a[m]) return m;if (elem < a[m]) return search(elem, a, low, m-1);return search(elem, a, m+1, high);
}
2 3 5 7 11 13 17 19
low
m
high
0 1 2 3 4 5 6 7
low = 6, high = 7
m = 6
6
Seite 924.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Beispiel: grter gemeinsamer Teiler
static int gcd (int x, int y) {
int rest = x % y;
while (rest != 0){
x = y; y = rest;
rest = x % y;
}
return y;
}
static int gcd (int x, int y)
{
int rest = x % y;
if (rest == 0) return y;
else return gcd(y, rest);
}
rekursiv iterativ
Seite 1024.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Beispiel: Die Trme von Hanoi
Gegeben sind 3 Pfosten mit n Scheiben
(unterschiedlicher Gre)
Grundstellung: alle Scheiben nach Gre
geordnet auf Pfosten A
Ziel: Lege alle n Scheiben von A nach C
Restriktion 1: jeweils nur eine Scheibe darf bewegt werden
Restriktion 2: niemals darf eine grere auf einer kleineren Scheibe liegen
Lsungsstrategie:
Problem allg. fr Turm der Hhe n lsen; folgende Flle sind zu unterscheiden
n = 0: gar nichts machen
n > 0:
(1) Turm der Hhe n-1 von A nach B bewegen (mittels C)
(2) Scheibe von A nach C legen
(3) Turm der Hhe n - 1 von B nach C bewegen (mittels A)
A B C
Seite 1124.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Beispiel: Trme von Hanoi
Rekursiver Algorithmus
import java.io.*;
public class Hanoi {
public static void verlegeTurm(int hoehe, int von,
int nach, int ueber) {
if (hoehe > 0) {
verlegeTurm(hoehe-1, von, ueber, nach);
System.out.println("von "+von + " nach "+ nach);
verlegeTurm(hoehe-1, ueber, nach, von);
}
}
public static void main(String[] args) throws IOException {
BufferedReader in = Text.open(System.in);
int hoehe = Text.readInt(in);
verlegeTurm(hoehe, 1, 2, 3);
}
}
A B C
Seite 1224.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Beispiel: Fibonacci-Funktion
Rekursiver Algorithmus
Fibonacci-Funktion
fib(n) = 1 fr n= 1, 2 und
fib(n) = fib(n-1) + fib(n-2) fr n > 2
Rekursiver Algorithmus zur Berechnung der Fibonacci-Zahlen
public class Fib {
public static int fib(int n) {
if (n
Seite 1324.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Effizienzuntersuchung Fibonacci:
Rekursive Implementierung
da bei Aufrufen der fib()-Methode stets die gleichen Schritte ausgefhrt werden,
ist Aufwand (mit c bezeichnet) proportional zur Anzahl der Aufrufe der Methode
Abschtzung Anzahl rekursiver Aufrufe von fib in Abhngigkeit von n
es gilt: c1 = c2 = 1
fr n > 2: cn = 1 + cn-1 + cn-2bei n > 3: cn-1= 1 + cn-2 + cn-3, also cn-2 = cn-1 - 1 - cn-3.
Einsetzen von cn-1 in Gleichung cn
cn = 2 + 2cn-2 + cn-3 > 2cn-2 > 22cn-4 > 2
3cn-6 > ...> 2n DIV2-1c2
also cn > 2n DIV2-1 (ist eine Untergrenze fr cn)
cn = 1 + cn-1 + cn-2 = 2cn-1 - cn-3 < 2cn-1< 22cn-2
Seite 1424.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Effizienzuntersuchung Fibonacci-Funktion:
Iterative Implementierung
Abschtzung der Anzahl der ausgefhrte Schritte (Anweisungen)
cn = 5 + (n-2)*3 + 1
iterative Fibonacci-Algorithmus erfordert mit n linear wachsenden Aufwand
public static long fibIt(int n) {
long fibN = 0;
long fibN1 = 1; // fuer Fib(n-1);
long fibN2 = 1; // fuer Fib(n-2);
if (n == 1) return 1;
else if (n == 2) return 1;
for (int i=3; i
Seite 1524.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Beispiel: Ackermann-Funktion
ack(n,m) =
m + 1 falls n=0
ack(n-1,1) falls m=0
ack(n-1,ack(n,m-1)) sonst
Vorsicht: Funktion wchst sehr stark: ack(4,2) besitzt 19729 Stellen
ack(4,4) ist grer als 10 hoch 10 hoch 10 hoch 1900
public static int ack(int n, int m) {
if (n == 0)
return m + 1;
else if (m == 0)
return ack(n-1,1);
else
return ack(n-1,ack(n,m-1));
}
Definition
Beispiele
Eigenschaften rekursiver Algorithmen
Seite 1624.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Eigenschaften rekursiver Algorithmen
Agenda
Seite 1724.1.2006,Bernhard Humm: Grundlagen der Programmierung I (Java). FH Darmstadt, WS 2005/2006
Vor- und Nachteile rekursiver Algorithmen
Anmerkung
zu jedem rekursiv formulierten Algorithmus gibt es einen quivalenten iterativen
Algorithmus
Vorteile rekursiver Algorithmen
krzere Formulierung
leichter