12. Rekursion Grundlagen der Programmierung 1 (Java)



Ähnliche Dokumente
4. Algorithmen und Datenstrukturen I Grundlagen der Programmierung 1 (Java)

II.3.1 Rekursive Algorithmen - 1 -

III.1 Prinzipien der funktionalen Programmierung - 1 -

Rekursive Funktionen

11. Komponenten Grundlagen der Programmierung 1 (Java)

FHZ. K13 Rekursion. Lernziele. Hochschule Technik+Architektur Luzern Abteilung Informatik, Fach Programmieren. Inhalt

Rekursive Funktionen

Gliederung. n Teil I: Einleitung und Grundbegriffe. n Teil II: Imperative und objektorientierte Programmierung

Rekursion. Sie wissen wie man Programme rekursiv entwickelt. Sie kennen typische Beispiele von rekursiven Algorithmen

n 1. Der Begriff Informatik n 2. Syntax und Semantik von Programmiersprachen - 1 -

Vorkurs Informatik WiSe 16/17

8. Generics Grundlagen der Programmierung 1 (Java)

Vorkurs Informatik WiSe 17/18

Lösungsvorschlag Serie 2 Rekursion

Stack. Seniorenseminar Michael Pohlig

Rekursion. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Institut fu r Informatik

9. Fehler und Ausnahmen Grundlagen der Programmierung 1 (Java)

1. Grundkonzepte der logischen Programmierung 2. Syntax von Prolog 3. Rechnen in Prolog. IV.1 Grundkonzepte der logischen Programmierung - 1 -

11. Rekursion. - Wiederholung von Anweisungen: durch Iteration und Rekursion - Anwendungsfälle der Rekursion

Programmiertechnik Methoden, Teil 2

Klassenvariablen, Klassenmethoden

To know recursion, you must first know recursion. Borchers: Programmierung für Alle (Java), WS 06/07 Kapitel 17 1

Programmieren in C. Rekursive Funktionen. Prof. Dr. Nikolaus Wulff

1.3 Welche Schritte werden bei der Programmerstellung benötigt? 1.5 Was sind Variablen im Kontext der Programmierung?

Algorithmen und Datenstrukturen Tafelübung 4. Jens Wetzl 15. November 2011

Speicher und Adressraum

Rekursion. Dr. Philipp Wendler. Zentralübung zur Vorlesung Einführung in die Informatik: Programmierung und Softwareentwicklung

Methoden. Gerd Bohlender. Einstieg in die Informatik mit Java, Vorlesung vom

Technische Universität München WS 2012/13 Fakultät für Informatik Lösungsvorschläge zu Blatt 4 Dr. C. Herzog, M. Maalej 12.

Datenstrukturen. Mariano Zelke. Sommersemester 2012

4 Rekursionen. 4.1 Erstes Beispiel

1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen - 1 -

1. Der Begriff Informatik 2. Syntax und Semantik von Programmiersprachen - 1 -

Software Entwicklung 1

Beispiel 1: Fakultät

Java I Vorlesung 1 Einführung in Java

Schnittstellen, Stack und Queue

Theoretische Informatik. Ackermann-Funktion. Ali Eyerta

Grundlagen der Programmierung

Fragenkatalog ESOP WS 16/17

Babeș-Bolyai Universität Cluj Napoca Fakultät für Mathematik und Informatik Grundlagen der Programmierung MLG5005. Rekursion

Programm heute. Algorithmen und Datenstrukturen (für ET/IT) Definition Algorithmus. Wie beschreibt man Algorithmen?

9. Rekursion. 1 falls n 1 n (n 1)!, andernfalls. Experiment: Die Türme von Hanoi. Links Mitte Rechts. Mathematische Rekursion

Algorithmen und Datenstrukturen (für ET/IT)

7. Pakete Grundlagen der Programmierung 1 (Java)

Objektorientierte Programmierung

11. Rekursion. 1, falls n 1. n (n 1)!, andernfalls. Mathematische Rekursion. Rekursion in Java: Genauso! Unendliche Rekursion. n!

Großübung zu Einführung in die Programmierung

12. Rekursion. 1, falls n 1. n (n 1)!, andernfalls. Lernziele. Mathematische Rekursion. Rekursion in Java: Genauso! n! =

Einschub: Anweisungen und Bedingungen für PAP und Struktogramme (1)

11. Rekursion, Komplexität von Algorithmen

Rekursion. Annabelle Klarl. Einführung in die Informatik Programmierung und Softwareentwicklung

Objektorientierte Programmierung Studiengang Medieninformatik

Einstieg in die Informatik mit Java

Vorlesung Informatik 2 Algorithmen und Datenstrukturen

Institut für Programmierung und Reaktive Systeme 25. Januar Programmieren I. Übungsklausur

C++ - Kontrollstrukturen Teil 2

Schwerpunkte. Verkettete Listen. Verkettete Listen: 7. Verkettete Strukturen: Listen. Überblick und Grundprinzip. Vergleich: Arrays verkettete Listen

2. Algorithmische Methoden 2.1 Rekursion. 18. April 2017

10. Programmierungs-Phase: Objektorientierung Software Engineering

Einführung in die Programmierung WS 2009/10. Übungsblatt 7: Imperative Programmierung, Parameterübergabe

Programmierung für Mathematik HS11

Beispiel: Temperaturumwandlung. Imperative Programmierung. Schwerpunkte. 3. Grundlegende Sprachkonstruktionen imperativer Programme

4 Effizienz und Komplexität 3.1 1

Informatik I: Einführung in die Programmierung

Mathematische Rekursion

Institut für Programmierung und Reaktive Systeme 2. Februar Programmieren I. Übungsklausur

Rekursive Funktionen und ihre programmtechnische Umsetzung

Software Entwicklung 1. Rekursion. Beispiel: Fibonacci-Folge I. Motivation. Annette Bieniusa / Arnd Poetzsch-Heffter

Erste Java-Programme (Scopes und Rekursion)

! 1. Unterklassen und Vererbung! 2. Abstrakte Klassen und Interfaces! 3. Modularität und Pakete! 4. Ausnahmen (Exceptions) II.4.

Grundzüge der Wirtschaftsinformatik WS 2002/03. Wiederholung Java. Programmierzyklus. Heiko Rossnagel Problem

Heap vs. Stack vs. statisch. 6 Speicherorganisation. Beispiel Statische Variablen. Statische Variablen

2. Unterprogramme und Methoden

Programmiersprachen. Organisation und Einführung. Berthold Hoffmann. Studiengang Informatik Universität Bremen

Inhalt Kapitel 2: Rekursion

Heap vs. Stack vs. statisch. 6 Speicherorganisation. Beispiel Statische Variablen. Statische Variablen

Einstieg in die Informatik mit Java

Technische Informatik I Übung 3: Assembler

Transkript:

12. Rekursion Grundlagen der Programmierung 1 (Java) Fachhochschule Darmstadt Haardtring 100 D-64295 Darmstadt Prof. Dr. Bernhard Humm FH Darmstadt, 24. Januar 2006

Einordnung im Kontext der Vorlesung 1. Einführung 2. Einfache Programme 3. Kontrollstrukturen 4. Objekt-Orientierung I 5. Algorithmen und Datenstrukturen I 6. Interfaces 7. Pakete 8. Parametrisierte Typen (Generics) 10. Gutes Programmieren 11. Komponenten 12. Rekursion 13. Algorithmen und Datenstrukturen II 14. Objektorientierung II 15. Design 16. Die Java Klassenbibliothek I 17. Die Java Klassenbibliothek II 9. Fehler und Ausnahmen 24.1.2006, Seite 2

Agenda Definition Beispiele Eigenschaften rekursiver Algorithmen 24.1.2006, Seite 3

Definition von Rekursion Beispiel: Fakultät Eine Methode m() heißt rekursiv, wenn sie sich selbst aufruft m( ) m( ) m( ) n( ) m( ) direkt rekursiv indirekt rekursiv Beispiel: Berechnung der Fakultät (n!) n! = 1 * 2 * 3 *... * (n-1) * n (n-1)! rekursive Definition n! = (n-1)! * n 1! = 1 Rekursive Methode zur Berechnung der Fakultät 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 24.1.2006, Seite 4

Ablauf einer rekursiven Methode Beispiel: Fakultät n = 4 24 long fact (long n) { if (n == 1) return 1 else return fact(n-1) * n; Jede Aktivierung von fact hat ihr eigenes n und rettet es über den rekursiven Aufruf hinweg n = 3 6 long fact (long n) { if (n == 1) return 1 else return fact(n-1) * n; n = 2 2 long fact (long n) { if (n == 1) return 1 else return fact(n-1) * n; n = 1 1 long fact (long n) { if (n == 1) return 1 else return fact(n-1) * n; 24.1.2006, Seite 5

Agenda Definition Beispiele Eigenschaften rekursiver Algorithmen 24.1.2006, Seite 6

Beispiel: binäres Suchen rekursiv z.b. Suche von 17 (Array muss sortiert sein) a 0 2 1 3 2 5 3 7 4 11 5 13 6 17 7 19 Index m des mittleren Element bestimmen 17 > a[m] in rechter Hälfte weitersuchen low m high a 0 2 1 3 2 5 3 7 4 11 5 13 6 17 7 19 low m high 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 24.1.2006, Seite 7

Ablauf des rekursiven binären Suchens elem = 17, low = 0, high = 7 6 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); m = 3 0 1 2 3 4 5 6 7 2 3 5 7 11 13 17 19 low m high low = 4, high = 7 6 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); m = 5 0 1 2 3 4 5 6 7 2 3 5 7 11 13 17 19 low m high low = 6, high = 7 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); 6 m = 6 0 1 2 3 4 5 6 7 2 3 5 7 11 13 17 19 low m high 24.1.2006, Seite 8

Beispiel: größter gemeinsamer Teiler rekursiv static int gcd (int x, int y) { int rest = x % y; if (rest == 0) return y; else return gcd(y, rest); iterativ static int gcd (int x, int y) { int rest = x % y; while (rest!= 0){ x = y; y = rest; rest = x % y; return y; 24.1.2006, Seite 9

Beispiel: Die Türme von Hanoi Gegeben sind 3 Pfosten mit n Scheiben (unterschiedlicher Größe) Grundstellung: alle Scheiben nach Größe geordnet auf Pfosten A A B C Ziel: Lege alle n Scheiben von A nach C Restriktion 1: jeweils nur eine Scheibe darf bewegt werden Restriktion 2: niemals darf eine größere auf einer kleineren Scheibe liegen Lösungsstrategie: Problem allg. für Turm der Höhe n lösen; folgende Fälle sind zu unterscheiden n = 0: gar nichts machen n > 0: (1) Turm der Höhe n-1 von A nach B bewegen (mittels C) (2) Scheibe von A nach C legen (3) Turm der Höhe n - 1 von B nach C bewegen (mittels A) 24.1.2006, Seite 10

Beispiel: Türme 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); A B C public static void main(string[] args) throws IOException { BufferedReader in = Text.open(System.in); int hoehe = Text.readInt(in); verlegeturm(hoehe, 1, 2, 3); 24.1.2006, Seite 11

Beispiel: Fibonacci-Funktion Rekursiver Algorithmus Fibonacci-Funktion fib(n) = 1 für n= 1, 2 und fib(n) = fib(n-1) + fib(n-2) für n > 2 Rekursiver Algorithmus zur Berechnung der Fibonacci-Zahlen public class Fib { public static int fib(int n) { if (n <= 2) else return 1; return fib(n-1) + fib(n-2); Algorithmus heißt effektiv, wenn er nach endlich vielen Schritten das korrekte Ergebnis liefert Algorithmis heißt effizient, wenn das Ergebnis mit einem Aufwand erreicht wird, der innerhalb vorgegebener Grenzen liegt 24.1.2006, Seite 12

Effizienzuntersuchung Fibonacci: Rekursive Implementierung da bei Aufrufen der fib()-methode stets die gleichen Schritte ausgeführt werden, ist Aufwand (mit c bezeichnet) proportional zur Anzahl der Aufrufe der Methode Abschätzung Anzahl rekursiver Aufrufe von fib in Abhängigkeit von n es gilt: c 1 = c 2 = 1 für n > 2: c n = 1 + c n-1 + c n-2 bei n > 3: c n-1 = 1 + c n-2 + c n-3, also c n-2 = c n-1-1 - c n-3. Einsetzen von c n-1 in Gleichung c n c n = 2 + 2c n-2 + c n-3 > 2c n-2 > 2 2 c n-4 > 2 3 c n-6 >...> 2 n DIV2-1 c 2 also c n > 2 n DIV2-1 (ist eine Untergrenze für c n ) c n = 1 + c n-1 + c n-2 = 2c n-1 - c n-3 < 2c n-1 < 2 2 c n-2 <...< 2 n-1 c 1 also c n < 2 n-1 (ist eine Obergrenze für c n ) Fibonacci-Methode erfordert mit n exponentiell wachsenden Aufwand, folglich ist Implementierung nicht effizient für große n. Gibt es effizientere Implementierungen? 24.1.2006, Seite 13

Effizienzuntersuchung Fibonacci-Funktion: Iterative Implementierung 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 <= n; i++) { fibn = fibn1 + fibn2; fibn2 = fibn1; fibn1 = fibn; System.out.println("Fib "+n+ " = "+fibn); return fibn; Abschätzung der Anzahl der ausgeführte Schritte (Anweisungen) c n = 5 + (n-2)*3 + 1 iterative Fibonacci-Algorithmus erfordert mit n linear wachsenden Aufwand 24.1.2006, Seite 14

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 wächst sehr stark: ack(4,2) besitzt 19729 Stellen ack(4,4) ist größer 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)); 24.1.2006, Seite 15

Agenda Definition Beispiele Eigenschaften rekursiver Algorithmen 24.1.2006, Seite 16

Vor- und Nachteile rekursiver Algorithmen Anmerkung zu jedem rekursiv formulierten Algorithmus gibt es einen äquivalenten iterativen Algorithmus Vorteile rekursiver Algorithmen kürzere Formulierung leichter verständliche Lösung Einsparung von Variablen teilweise sehr effiziente Problemlösungen (z.b. Quicksort) Bei rekursiven Datenstrukturen (zum Beispiel Bäume, Graphen) besonders empfehlenswert Nachteile rekursiver Algorithmen weniger effizientes Laufzeitverhalten (Overhead bei Funktionsaufruf) Verständnisprobleme bei Programmieranfängern Konstruktion rekursiver Algorithmen "gewöhnungsbedürftig" 24.1.2006, Seite 17

Rekursion in Programmiersprachen Nicht alle Programmiersprachen unterstützen rekursive Algorithmen Rekursion erlaubt: ALGOL-Familie (ALGOL 60, Simula 67, ALGOL 68, PASCAL, MODULA-2, Ada) PL/1 C und C++ Java C# Rekursion nicht möglich: FORTRAN COBOL LISP arbeitet überwiegend mit rekursiven Algorithmen (gilt i.d.r. auch für PROLOG) 24.1.2006, Seite 18