Algoritmer och datastrukturer Rekursiva funktioner Frelsning 10 Weiss







![En rekursiv process kräver minne sum( [7, 3, 6, 4, 2, 9] ) 7 En rekursiv process kräver minne sum( [7, 3, 6, 4, 2, 9] ) 7](https://slidetodoc.com/presentation_image_h/170f965441677eb518f4dc94b640bbf5/image-8.jpg)




























- Slides: 36
Algoritmer och datastrukturer Rekursiva funktioner Föreläsning 10 (Weiss kap. 7) u Induktion och rekursion u Rekursiva funktioner och processer u Weiss 7. 1 -3 u Fibonaccital 7. 3. 4 u Exempel: Balansering av mobil u Exempel: Tornen i Hanoi ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ (7. 4, 7. 5. 3 utgår) Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 (kod se lab 5) Förel. 10 - Rekursiva algoritmer Nr: 11 1
Ex. Räkna personer i en grupp – utan global överblick …. . 2 1? : -( : -| : -) N-2 ? höger : -o : -| : -) N-1 ? : -o : -| : -) #? N : -o : -| : -) : -0 : -) SCB Rekursionsantagande: Denna grupp klarar att räkna sig själv. Varje person exekverar följande rekursiva algoritm: 1. Om ingen står till vänster så ropa 1 åt höger 2. Annars, fråga grannen till vänster hur många de är. Om svaret är K så ropa K+1 åt höger. ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 2
Induktiva definitioner och rekursion Ex. Induktiv definition av lista Basfall En lista är antingen (1) tom eller (2) ett element följt av en lista Induktionsfall ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 3
Ex. Summera elementen i en lista - rekursiv process 7(3 +(2 sum( [6, 4, 2, 9] ))) 7 + (3 (6 +++(3 7 +(37 + (4 +++ +(6 (3 7(4 + (2 7+ +++(6 (4 + (3 (4 (6 sum( 7+ (9 + ++++sum( + (6 sum( (4 [7, 3, 6, 4, 2, 9] (3 sum( 7 + [3, 6, 4, 2, 9] +++ + (9 (4 [4, 2, 9] (2 (6 [2, 9] (3 ++[]7 +++ 0))))) 11))) )))))) 9)))) 15)) 21) ))) 7 ++77(3 (6 +sum( +(2 sum( [9] ))))) 31 + 24 Rekursiv algoritm: 1. Om listan är tom är summan av elementen 0 2. Annars, summera elementen i resten av listan och addera första elementet till resultatet ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 4
En rekursiv listsummeringsfunktion int sum( List. Node l ) { if ( l == null ) return 0; // Basfall else // Rekursionssteg return l. element + sum( l. next ); } Rekursionsantagande: Algoritmen kan summera elementen i en kortare lista. ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 5
Iterativa och rekursiva processer Iterativ process u En iterativ process (loop) har konstant minnesbehov (i princip) Rekursiv process u En rekursiv process har variabelt minnesbehov – oftast används en stack u Anropsstack och aktiveringsposter – Lokala funktionsvariabler lagras i aktiveringsposter, en per funktionsanrop – När en funktion anropas (aktiveras) läggs en aktiveringspost på anropsstacken. Den frigörs vid retur. 6 ©Uno Holmer, Chalmers, 2021 -02 -27 Algoritmer och datastrukturer Förel. 10 - Rekursiva algoritmer www. cse. chalmers. se/~holmer/ LET 375, DAI 2+I 2, 18/19, lp 4 Nr: 11
En iterativ listsummeringsfunktion int sum( List. Node l ) { int s = 0; while ( l != null ) { s = s + l. element; l = l. next; } return s; } ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 7
En rekursiv process kräver minne sum( [7, 3, 6, 4, 2, 9] ) 7 + sum( [3, 6, 4, 2, 9] ) 7 + (3 + sum( [6, 4, 2, 9] )) 7 + (3 + (6 + sum( [4, 2, 9] ))) 7 + (3 + (6 + (4 + sum( [2, 9] )))) 7 + (3 + (6 + (4 + (2+ sum( [9] ))))) 7 + (3 + (6 + (4 + (2 + (9 + sum( [] )))))) 7 + (3 + (6 + (4 + (2 + (9 + 0))))) Maximalt minnesbehov 7 + (3 + (6 + (4 + (2 + 9))))) 7 + (3 + (6 + (4 + 11)))) 7 + (3 + (6 + 15))) 7 + (3 + 21) 7 + 24 31 ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 8
Två exempel i Weiss u Summering av tal rekursivt (Fig. 7. 1) u Utskrift av heltal i valfri bas (Fig. 7. 2 -4) ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 9
Summering av serie 1 4 5 6 7 8 9 10 //Evaluate the sum of the first n integers public static long s( int n ) { if ( n == 1 ) return 1; else return s( n - 1 ) + n; } Figure 7. 1 Recursive evaluation of the sum of the first N integers ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 10
Rekursiv utskrift av heltal i decimal form kvot (/10) rest (%10) 7364 736 Skriv först ut detta tal rekursivt 4 Skriv därefter ut detta ensiffriga tal Basfall: Om talet är ensiffrigt kan det skrivas ut direkt ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 11
Utskrift av heltal i decimal form 1 2 3 4 5 6 7 8 // Print n in base 10, recursively. // Precondition: n >= 0. public static void print. Decimal( long n ) { if ( n >= 10 ) print. Decimal( n / 10 ); System. out. print( (char)(’ 0’ + (n % 10))); } Figure 7. 2 Recursive routine for printing N in decimal form ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 12
Stackens roll vid rekursion S( 5 ) 15 S( N 10 - + 1 )N + N S( N 6 - +1 N ) +N S( N 3 - +1 N ) +N S( N 1 -+1 N) + N Anropsstacken N 1 N 2 N 3 N 4 N 5 1 ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 13
Förgreningsrekursion Exempel: En Mobil är antingen 1. en fisk m eller 2. på formen m 1 m 3 snöre l 1 m 2 l 2 stång snöre Mobil m 3 Mobil m 1 ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 m 2 Förel. 10 - Rekursiva algoritmer Nr: 11 14
Är min mobil balanserad? Balanserad Oba m 3 m 1 e rad e s n la m 2 m 3 m 5 m 1 ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ m 2 Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 m 2 m 4 Förel. 10 - Rekursiva algoritmer Nr: 11 15
Vad väger en mobil? 1. vikt( )=m m 2. vikt( ) = vikt( M 1 ) + vikt( M 2 ) M 1 M 2 Rekursionsantagande: Denna metod kan räkna ut vikterna hos M 1 och M 2 ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 16
När är en mobil balanserad? 1. En fisk är alltid balanserad 2. En mobil på formen l l är balanserad 1 M 1 2 M 2 om och både M 1 och M 2 är balanserade Rekursionsantagande: Denna metod kan avgöra om M 1 och M 2 är balanserade ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 17
Fibonaccitalen 1 1 2 3 5 8 13 21 34 55 89. . . 0 1 ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ 2 3 4 5 6 7 Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 8 9 10. . . Förel. 10 - Rekursiva algoritmer Nr: 11 18
”Gyllene snittet” b a a=1 G vis k n a r t b ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 19
Rekursiv beräkning av Fibonaccital 1 2 3 4 5 6 7 8 9 // Compute the Nth Fibonacci Number. // Bad algorithm. long fib( int n ) { if ( n <= 1 ) return 1; else return fib( n - 1 ) + fib( n - 2 ); } Figure 7. 6 Recursive routine for Fibonacci Numbers: A bad idea. ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 20
Problem med Fib fib(5) fib(3) fib(1) fib(4) fib(2) fib(0) fib(1) fib(3) fib(1) fib(2) fib(0) fib(1) - Hur många funktionsanrop genererar anropet fib(N)? ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 21
Iterativ beräkning av Fibonaccital previous. Fib current. Fib 1 1 2 3 5 8 13 21 34 55 89. . . current. Fib 1 1 2 3 5 8. . . 83512 + 53120 previous. Fib ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 22
Skriv ut de N minsta Fibonaccitalen iterativt med loop void fib. Iter. Print( int n ) { long previous. Fib = 0, current. Fib = 1; for ( int i = n; i > 0; i-- ) { System. out. println( current. Fib ); long next. Fib = previous. Fib + current. Fib; previous. Fib = current. Fib; current. Fib = next. Fib; } } Övning: Variabeln next. Fib är överflödig, eliminera den! ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 23
Returnera det N: te Fibonaccitalet iterativt med loop long fib. Iter( int n ) { long previous. Fib = 0, current. Fib = 1; for ( int i = n; i > 0; i-- ) { long next. Fib = previous. Fib + current. Fib; previous. Fib = current. Fib; current. Fib = next. Fib; } return current. Fib; } ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 24
Fibonaccital med iterativ rekursion s. k. ”svansrekursion” void fib. Iter. Rek. Print(long previous. Fib, long current. Fib, int n) { if ( n == 0) return; else { System. out. println( current. Fib ); fib. Iter. Rek. Print( current. Fib, previous. Fib + current. Fib, n - 1 ); } } void fib. Print( int n ) { fib. Iter. Rek. Print(0, 1, n); } u Denna typ av rekursion kan av en optimerande kompilator automatiskt översättas till en loop ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 25
Returnera det N: te Fibonaccitalet iterativ rekursion long fib. Iter. Rek( long previous. Fib, long current. Fib, int n ) { if ( n == 0) return current. Fib; else return fib. Iter. Rek( current. Fib, previous. Fib + current. Fib, n - 1 ); } long fib( int n ) { return fib. Iter. Rek( 0, 1, n ); } ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 26
Tornen i Hanoi u u N st. ringar av olika diametrar är uppträdda på en pinne Ingen ring ligger ovanpå en mindre ring A B C Problem Flytta alla ringarna från pinne A till pinne B Regler u Högst en ring får flyttas åt gången u En ring får bara läggas ovanpå en större ring ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 27
Flytta två ringar från A till C via B A ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ B Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 C Förel. 10 - Rekursiva algoritmer Nr: 11 28
Flytta en ring från A till B A ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ B Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 C Förel. 10 - Rekursiva algoritmer Nr: 11 29
Flytta två ringar från C till B via A A ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ B Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 C Förel. 10 - Rekursiva algoritmer Nr: 11 30
Flytta N ringar från A till B via C N-1 { Övriga ringar } Rekursionsantagande: Metoden kan flytta en stapel av höjd N-1 på korrekt sätt }N A ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ N-1 Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 B C Förel. 10 - Rekursiva algoritmer Nr: 11 31
Implementering u Programmet skall skriva ut en ”arbetsinstruktion” enligt följande modell: Number of rings? 3 Do the following moves: A --> B A --> C B --> C A --> B C --> A C --> B A --> B ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 32
En rekursiv algoritm för Hanois torn from 1 2 3 4 5 6 7 8 9 10 11 12 13 14 to via void move( char a, char b, char c, int n ) { if ( n > 0 ) { // move n - 1 rings from a to c via b move( a, c, b, n - 1 ); System. out. println( a + " --> " + b ); // move n - 1 rings from c to b via a move( c, b, a, n - 1 ); } } void hanoi( int n ) { move( 'A', 'B', 'C', n ); } ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 33
Tidskomplexiteten hos Hanoi Definition: Låt T(N) vara antalet ringförflyttningar som utförs av anropet move( X, Y, Z, N) för att flytta en stapel av N ringar från X till Y via Z. Sats: För alla d. v. s. gäller att Bevis: Induktion över N. Låt P(X) vara påståendet: Visa att P(N) gäller för varje ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 34
Bevis av satsen Vi gör induktion över N. Basfall: Visa att P(0) håller, d. v. s. Om move anropas med N = 0 är villkoret på rad 2 falskt och funktionen terminerar direkt, vilket stämmer eftersom ingenting skall flyttas om vi inte har några ringar alls! ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 35
Induktionssteg: Visa att P(N) håller för godtyckligt N > 0, d. v. s. Induktionsantagande: Antag P(k) är sant för alla k < N 1. Först anropas move(A, C, B, N-1) (rad 4) Induktionsantagandet gäller för varje k < N och speciellt för N - 1, d. v. s. 2. Därefter flyttas en ring från A till B (rad 6) 3. Sist anropas move(C, B, A, N-1) (rad 9) Av induktionsantagandet följer att detta ger ytterligare förflyttningar Det totala antalet förflyttningar, T(N), blir således ©Uno Holmer, Chalmers, 2021 -02 -27 www. cse. chalmers. se/~holmer/ Algoritmer och datastrukturer LET 375, DAI 2+I 2, 18/19, lp 4 Förel. 10 - Rekursiva algoritmer Nr: 11 36