UE Algorithmen und Datenstrukturen 1 UE Praktische Informatik 1 Übung 7 Entrekursivierung Institut für Pervasive Computing Johannes Kepler Universität Linz Altenberger Straße 69, A-4040 Linz
Rekursive Algorithmen Vorteile Elegant Prägnant Kurz Nachteile (Schwerer nachvollziehbar) Schlechtere Effizienz Laufzeit Speicherbedarf In der Praxis oft nicht vertretbar Konsequenz: Rekursionen vermeiden oder beseitigen < 2 >
Entrekursivierung ::Vorgehensweise Rekursives Programm 1. Vorbereitung nur ein rekursiver Aufruf pro Zeile direkte Return-Anweisungen beseitigen 2. Automatenstruktur Schritte getrennt durch rekursive Aufrufe Schleife einbauen 3. Entrekursivieren noch mit Textanweisungen vollständiges entrekursiviertes Programm < 3 >
Entrekursivierung :: Beispiel Schritt 1 Folgender Algorithmus soll entrekursiviert werden: int W( int m int n) { if (m == 1 n == 1) { return m + n return W( m-1 n) + W( m n-1) < 4 >
Entrekursivierung :: Beispiel Schritt 2.1 1. Nur ein rekursiver Aufruf pro Zeile return m + n return W( m-1 n) + W( m n-1) return m + n w1 = W( m-1 n) w2 = W( m n-1) return w1 + w2 < 6 >
Entrekursivierung :: Beispiel Schritt 2.2 2. Direkte Return- Anweisung beseitigen return m + n w1 = W( m-1 n) w2 = W( m n-1) return w1 + w2 else { w1 = W( m-1 n) w2 = W( m n-1) < 7 >
Entrekursivierung :: Beispiel Schritt 3.1 Automatenstruktur: else { 1 W( m-1 n) w1= W( m n-1) 2 w2= 3 < 8 >
Entrekursivierung :: Beispiel Schritt 3.2 Automatenstruktur + Loop: int state = 1 while (state!=0) { switch(state) { case 1: state = 0 else { result = W( m-1 n) state = 2 Ist noch rekursiv! case 2: w1 = result result = W( m n-1) state = 3 case 3: w2 = result state = 0 // switch // while < 9 >
Entrekursivierung :: Beispiel Schritt 4.1 Entrekursiviert (noch textuell): int state = 1 while (state!= 0) { switch(state) { case 1: else { case 2: w1 = result case 3: w2 = result // switch // while < 10 >
Entrekursivierung :: Beispiel Schritt 4.1 Entrekursiviert (noch textuell): int state = 1 Kellerspeicher einrichten while (state!= 0) { switch(state) { case 1: else { case 2: w1 = result case 3: w2 = result // switch // while < 11 >
Entrekursivierung :: Beispiel Schritt 4.1 Entrekursiviert (noch textuell): int state = 1 Kellerspeicher einrichten while (state!= 0) { switch(state) { case 1: Abbruchbedingung erreicht -> Ende else { case 2: w1 = result case 3: w2 = result // switch // while < 12 >
Entrekursivierung :: Beispiel Schritt 4.1 Entrekursiviert (noch textuell): int state = 1 Kellerspeicher einrichten while (state!= 0) { switch(state) { case 1: Abbruchbedingung erreicht -> Ende else { relevante Variablen und nächsten Zustand einkellern Parameter einstellen state = 1 -> zum Start case 2: w1 = result case 3: w2 = result // switch // while < 13 >
Entrekursivierung :: Beispiel Schritt 4.1 Entrekursiviert (noch textuell): int state = 1 Kellerspeicher einrichten while (state!= 0) { switch(state) { case 1: Abbruchbedingung erreicht -> Ende else { relevante Variablen und nächsten Zustand einkellern Parameter einstellen state = 1 -> zum Start case 2: rel. Var. auskellern w1 = result rel. Var. und nächsten Zustand einkellern Parameter einstellen state = 1 -> gehe zum Start case 3: w2 = result // switch // while < 14 >
Entrekursivierung :: Beispiel Schritt 4.1 Entrekursiviert (noch textuell): int state = 1 Kellerspeicher einrichten while (state!= 0) { switch(state) { case 1: Abbruchbedingung erreicht -> Ende else { relevante Variablen und nächsten Zustand einkellern Parameter einstellen state = 1 -> zum Start case 2: rel. Var. auskellern w1 = result rel. Var. und nächsten Zustand einkellern Parameter einstellen state = 1 -> gehe zum Start case 3: rel. Var. auskellern w2 = result state = 0 -> Ende // switch // while < 15 >
Entrekursivierung :: Beispiel Schritt 4.1 Entrekursiviert (noch textuell): int state = 1 Kellerspeicher einrichten while (state!= 0) { switch(state) { case 1: Abbruchbedingung erreicht -> Ende else { relevante Variablen und nächsten Zustand einkellern Parameter einstellen state = 1 -> zum Start case 2: rel. Var. auskellern w1 = result rel. Var. und nächsten Zustand einkellern Parameter einstellen state = 1 -> gehe zum Start case 3: rel. Var. auskellern w2 = result state = 0 -> Ende // switch if (state ==0 && Keller nicht leer){ Folgezustand nach Rekursion auskellern // while < 16 >
Entrekursivierung :: Beispiel Schritt 4.2 Entrekursiviert (vollständiger Algorithmus): int state = 1 initstack() while (state!= 0) { switch(state) { case 1: state = 0 else { push( m); push( n) push( 2) m = m-1 state = 1 case 2: pop( n); pop( m) w1 = result push( w1) push( 3) n = n-1 state = 1 case 3: pop( w1) w2 = result state = 0 // switch if ((state == 0 &&!emptystack()) pop( state) // while < 17 >
Entrekursivierung :: Schreibtischtest State m n w1 w2 result Stack < 18 >
Entrekursivierung :: Schreibtischtest int state = 1 initstack() while (state!= 0) { switch(state) { case 1: state = 0 else { push( m); push( n) push( 2) m = m-1 state = 1 case 2: pop( n); pop( m) w1 = result push( w1) push( 3) n = n-1 state = 1 case 3: pop( w1) w2 = result state = 0 // switch if ((state == 0 &&!emptystack()) pop( state) // while < 19 >
Entrekursivierung :: Schreibtischtest State m n w1 w2 result Stack 1 2 3 < 20 >
Entrekursivierung :: Schreibtischtest int state = 1 initstack() while (state!= 0) { switch(state) { case 1: state = 0 else { push( m); push( n) push( 2) m = m-1 state = 1 case 2: pop( n); pop( m) w1 = result push( w1) push( 3) n = n-1 state = 1 case 3: pop( w1) w2 = result state = 0 // switch if ((state == 0 &&!emptystack()) pop( state) // while < 21 >
Entrekursivierung :: Schreibtischtest State m n w1 w2 result Stack 1 2 3 1 1 3 2,3,2 < 22 >
Entrekursivierung :: Schreibtischtest int state = 1 initstack() while (state!= 0) { switch(state) { case 1: state = 0 else { push( m); push( n) push( 2) m = m-1 state = 1 case 2: pop( n); pop( m) w1 = result push( w1) push( 3) n = n-1 state = 1 case 3: pop( w1) w2 = result state = 0 // switch if ((state == 0 &&!emptystack()) pop( state) // while < 23 >
Entrekursivierung :: Schreibtischtest State m n w1 w2 result Stack 1 2 3 1 1 3 2,3,2 0 1 3 4 2,3,2 < 24 >
Entrekursivierung :: Schreibtischtest int state = 1 initstack() while (state!= 0) { switch(state) { case 1: state = 0 else { push( m); push( n) push( 2) m = m-1 state = 1 case 2: pop( n); pop( m) w1 = result push( w1) push( 3) n = n-1 state = 1 case 3: pop( w1) w2 = result state = 0 // switch if ((state == 0 &&!emptystack()) pop( state) // while < 25 >
Entrekursivierung :: Schreibtischtest State m n w1 w2 result Stack 1 2 3 1 1 3 2,3,2 0 1 3 4 2,3,2 2 1 3 4 2,3 1 2 2 4 4 4,3 1 1 2 4 4 4,3,2,2,2 0 1 2 4 3 4,3,2,2,2 2 1 2 4 3 4,3,2,2 1 2 1 3 3 4,3,3,3 0 2 1 3 3 4,3,3,3 3 2 1 3 3 4,3,3 0 2 1 3 3 6 4,3 3 2 1 3 3 6 4 0 2 1 4 6 10 < 26 >
Entrekursivierung :: Schreibtischtest int state = 1 initstack() while (state!= 0) { switch(state) { case 1: state = 0 else { push( m); push( n) push( 2) m = m-1 state = 1 case 2: pop( n); pop( m) w1 = result push( w1) push( 3) n = n-1 state = 1 case 3: pop( w1) w2 = result state = 0 // switch if ((state == 0 &&!emptystack()) pop( state) // while < 27 >
Entrekursivierung :: Schreibtischtest State m n w1 w2 result Stack 1 2 3 1 1 3 2,3,2 0 1 3 4 2,3,2 2 1 3 4 2,3 1 2 2 4 4 4,3 1 1 2 4 4 4,3,2,2,2 0 1 2 4 3 4,3,2,2,2 2 1 2 4 3 4,3,2,2 1 2 1 3 3 4,3,3,3 0 2 1 3 3 4,3,3,3 3 2 1 3 3 4,3,3 0 2 1 3 3 6 4,3 3 2 1 3 3 6 4 0 2 1 4 6 10 < 28 >
Entrekursivierung :: Zusammenfassung Rekursives Programm 1. Vorbereitung nur ein rekursiver Aufruf pro Zeile direkte Return-Anweisungen beseitigen 2. Automatenstruktur Schritte getrennt durch rekursive Aufrufe Schleife einbauen 3. Entrekursivieren noch mit Textanweisungen vollständiges entrekursiviertes Programm < 29 >