21
© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 1 Chapter 17: Recursion Recursion is a function calling itself with a shorter input Recursion calls with shorter and shorter input until the input is trivial like null for which the function has a simple value like 0 without calling itself any further Recall we covered recursion in Chapter 10 as a reason why we need to use a stack (instead of some fixed locations declared below the function code) to save a function’s caller’s registers and the function’s local variables E.g., strlen(string) = 1 + strlen(rest of the string after the first character) The recursive call to strlen has one less character Next 2 slides are Ch. 10’s slides on strlen (slides 33-34 – chapter 10 starts at slide 31 and not slide 1)

Chapter 17: Recursion - Purdue Engineeringece495k/slides/ece495k-ch17.pdf · Chapter 17: Recursion ... • Recall we covered recursion in Chapter 10 as a reason why ... Chapter 17

Embed Size (px)

Citation preview

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 1

Chapter 17: Recursion

Recursion is a function calling itself with a shorter input•Recursion calls with shorter and shorter input until the input is trivial like null for which the function has a simple value like 0 without calling itself any further

•Recall we covered recursion in Chapter 10 as a reason why we need to use a stack (instead of some fixed locations declared below the function code) to save a function’s caller’s registers and the function’s local variables

•E.g., strlen(string) = 1 + strlen(rest of the string after the first character)

•The recursive call to strlen has one less character•Next 2 slides are Ch. 10’s slides on strlen (slides 33-34 –chapter 10 starts at slide 31 and not slide 1)

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 2

Chapter 17: Recursion

Please look at Ch 10 slides on recursion

For you to understand recursion, you need to spend time on this material and after reading the sides write the code yourself otherwise you won’t get it

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 3

Alternative String length routine pseudocode

Is current string address pointing at NUL?• If so, return 0•Else, call STRLEN with address incremented; add 1 to the

return value and return

l lH e !dlrowo

Length = 1 + STRLEN(“ello world!”)

•This is called recursion – function invokes itself (with smaller input)

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 4

Alternative String length routine pseudocode

• 1. Call Strlen (“Hello World!”) = 1 + call strlen (“ello World!”)

• 2. Strlen (“ello World!”) = 1 + call strlen (“llo World!”)

• 3. Strlen (“llo World!”) = 1 + call strlen (“lo World!”)

• ..

• n-1 strlen (“!”) = 1 + call strlen (“”)

• n. Strlen (“”) = 0 return

• n returns then n -1 returns then n-2 returns .. all the way to 1 returns (calls go down the slide and returns go up)

• As each left hand side returns, the previous right hand side gets the corresponding return value, adds 1, and itself returns

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 5

Recursion in C – StrLen example

#include <stdio.h>#define MAX_LEN 100int strLen(char *string);int main() {

char inputString[MAX_LEN]; /* inputString is char * type –last lecture */ printf (“Enter your string (less than MAX_LEN characters)”);scanf (“%s”, inputString);printf(“The length of the string is %d\n”, strLen(inputString));/* watch the type of argument to strLen- matches declaration*/

}

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 6

Recursion in C – strLen example

int strLen(char *string) {

if (*string != ‘\0’) {return (1 + strLen(string+1)); /* recursive call but the

argument “skips” the first character of whatever was given*/}else /* *string == ‘\0’ */

return 0; } Each recursive call’s argument is one character to the right of

the input it receives – every call’s “string” starts one character to right of previous call

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 7

Recursion in action

We use a slightly shorter input of just the word “Hello” here•LC-3 example uses “Hello World!”

• Recursive calls go from left to right over the above string (each recursive call moves right by one character) and returns go right to left (returns have to be in reverse order of calls)

• Details on next slide

H le l o

[0] [1] [2] [3] [4] [5]

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 8

Recursion in action

• Main calls strLen(string+0) which calls strLen(string+1) which calls strLen(string+2) which calls strLen(string+3) which calls strLen(string+) which calls strLen(string+5) which returns 0 to strLen(string+4) which returns 1+0 = 1 to strLen(string+3) which returns 1+1 = 2 to strLen(string+2) which returns 1+2 = 3 to strLen(sring+1] which returns 1+3 = 4 to strLen(string+0) which returns 1+4 = 5 to main

• Next 4 slides are ch. 10’s slides 35, 46-48 (input is “Hello World!” instead of “Hello”)

•Part A on slide 10 is the “if clause” in our strLen function in C and part B is the “else clause”

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 9

Converting recursive string length to code

Is current string address pointing at NUL? LDR into R2 will set CCRs (must save R2)

• If so, return 0 – BRz, fill 0 into R0, return•Else, invoke STRLEN with address incremented; add 1 to

the return value and return – add 1 to R0, JSR to STRLEN (must save R7), add 1 to R0, return

l lH e !dlrowo

Length = 1 + STRLEN(“ello world!”)

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 10

Stack-based recursive STRLEN

STRLEN ADD R6, R6, #-2 ; decrement to push 2 STR R7, R6, #1 ; save R7 (return PC)STR R2, R6, #0 ; save R2 (test char)

TEST LDR R2, R0, #0 ; check current charBRz DONE ; found NULADD R0, R0, #1 ; increment addressJSR STRLEN ; call recursivelyADD R0, R0, #1 ; increment lengthBRnzp REST ; restore and return

DONE AND R0, R0, #0 ; length result is 0REST LDR R2, R6, #0 ; restore R2

LDR R7, R6, #1 ; restore R7ADD R6, R6, #2 ; increment for pop 2RET ; return to main code

AB

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 11

Stack-based recursive STRLEN

Strlen called with “Hello World!”execute A1 --> call strlen “ello World!”execute A2 --> call strlen “llo World!”execute A3 ..execute A12 --> call strlen “” NULLexecute A13 --> doesn't call strlen and returns 0

execute B12 --> returns 0+1 = 1execute B11 --> returns 1+1 = 2..execute B2 --> returns 10+1 = 11execute B1 --> returns 11+1 = 12

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 12

Stack-based recursive STRLEN

Strlen called with “Hello World!”execute A1 --> push A1's R2, R7 on stackexecute A2 --> push A2's R2, R7 on stackexecute A3 .. stack keeps growingexecute A12 --> push A12's R2, R7 on stackexecute A13 --> push R2,R7, later pop R2,R7, return

execute B12 --> pop A12's R2, R7 from stackexecute B11 --> pop A11's R2, R7 from stack.. stack keeps shrinkingexecute B2 --> pop A2's R2, R7 from stackexecute B1 --> pop A1's R2, R7 from stack

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 13

Recursion vs. iteration

Technically all recursive functions can be rewritten using iterations (theoretically possible)

But some code is easier and simpler using recursion and other code is simpler with iteration

Knowing which of recursion or iteration is easier for a given problem will come with experience and practice

In general, recursion is usually more expensive in run time than iteration

• But if recursion is easier to program then it may be worth it

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 14

Recursion

Key to writing recursive code

1. Figure out how to invoke recursively on smaller problem1. Figure out what the smaller problem is2. Figure out what to do before or after invoking smaller

problem

2. Figure out ending condition

Ch. 17 has other examples (sections 17.4 and 17.5)•The concepts are the same•You should write out the code of our example on your own

to learn how recursion works – without writing the code yourself you will not full understand recursion

•We skip 17.6

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 15

A more serious recursion example

Towers of Hanoi (example in section 17.3)Problem: Move a bunch of disks from start port to end post

and use an intermediate post

Constraints:1. Only one disk moved at a time2. A larger disk can not be placed on a smaller disk

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 16

A more serious recursion example

Move n disks from start post to end postRecursion expression: we need to think of breaking up the big

problem into smaller sub-problems (which are solved recursively)

•Move n-1 disks from start post to intermediate post •Move nth disk from start post to end post•Move n-1 disks from intermediate post to end post

Termination:•Move the smallest disk from start post to end post

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 17

A more serious recursion example

How do we know our recursion expression satisfies the two constraints (this is not in the book)

•We move only one disk at a time (1st constraint) – either the largest disk of a sub-problem or disk 1

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 18

A more serious recursion example

•2nd constraint is more involved: for any sub-problem – The first call moves disks from start post to intermediate

post which is empty (end post is empty, so can be used freely)

– The move moves the largest disk in the sub-problem to the end post which is empty

– The last call moves all but one disks in the sub-problem from the mid post to the end post which has the largest disk (the other disks are smaller, so no violation and start post (used as intermediate) has disks larger than the subproblem)

– Termination moves disk 1 which is smaller than all other disks, so can be put on top of others

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 19

A more serious recursion example

MoveDisk (diskNumber, startPost, endPost, midPost) {if (diskNumber > 1) {

/* move n-1 disks from start to intermediate */MoveDisk (diskNumber -1, startPost, midPost, endPost);/* move nth disk from start to end */printf (“Move disk %d from post %d to post %d\n”,

diskNumber, startPost, endPost);/* move n-1 disks from intermediate to end */moveDisk(diskNumber-1, midPost, endPost, startPost);

} else printf (“Move disk 1 from post %d to post %d\n”,

startPost, endPost);

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 20

A more serious recursion example

0. MoveDisk(3, 1, 3 , 2) (top level call)1. MoveDisk (2,1, 2, 3) (0’s 1st call) (endpost and midpost roles

changed)2. MoveDisk(1, 1, 3, 2) (1’s 1st call) (roles change again)“Move disk 1 from post 1 to post 3” (2 returns)“Move disk 2 from post 1 to post 2” (1’s print)3. MoveDisk (1, 3, 2, 1) (1’s last call)“Move disk 1 from post 3 to post 2” (3 returns then 1 returns)“Move disk 3 from post 1 to post 3” (0’s print)4. MoveDisk (2, 2, 3, 1) (0’s last call)5. MoveDisk (1, 2, 1, 3) (4’s 1st call)“Move disk 1 from post 2 to post 1” (5 returns)

© 2009 Vijaykumar ECE495K Lecture Notes: Chapter 17 21

A more serious recursion example“Move disk 2 from post 2 to post 3” (4’s print)6. moveDisk(1,1,3,2) (4’s last call)“Move disk 1 from post 1 to post 3 (6 returns, then 4 returns,

then 0 returns)

Note that the roles of the posts keep changing

Do you think iterative code will be easier than this?