Chapter 25 Recursion Syllabus sections covered: 4.1.4 Teaching resources Topics 1 2 3 4 Syllabus 40 min. section periods Concept of recursion 4.1.4 1 Programming recursive 4.1.4 5 subroutines Resources in the coursebook Tracing a recursive subroutine Execution of a recursive subroutine Worked Example 25.01 Task 25.01 Question 25.01 Worked Example 25.02 4.1.4 3 Task 25.02 4.1.4 6 Worked Example 25.03 *Task 25.03 Exam-style Question 1 Exam-style Question 2 **Exam-style Question 3 Resources on this CD-ROM Exercise 25.01 Exercise 25.02 Exercise 25.03 **Exercise 25.04 Exercise 25.05 Tasks and exercises marked * are for students who have completed the basic exercises. Tasks and exercises marked ** are stretch and challenge exercises. Past exam paper questions Paper 9691/22 9691/21 9691/23 9691/32 9691/33 9691/31 9691/33 Series June 2014 June 2012 June 2011 Nov 2013 Nov 2013 June 2013 June 2013 Question 4 5 4 5 5 4 4 Supporting notes Recursion is a difficult concept to grasp. Students need lots of practice at writing recursive routines and tracing the execution of these. 25.01 Topic 1 Concept of recursion Coursebook section 25.01 Concept of recursion Teaching ideas Build on students’ previous experience of recursive definitions in mathematics (such as the factorial function). There are other everyday tasks that can be described in a recursive way: © Cambridge University Press 2016 • Purchasing items on a shopping list: get the first item on the list; purchase remaining items on shopping list. • Writing numbers from 1 to n: write numbers from 1 to (n-1); write n. • Writing numbers from n down to 1: write n; write numbers from (n-1) down to 1 (see Worked Example 25.02). • Writing the alphabet backwards: let z be the nth character, write nth character; write letters (n-1) to 1. • Binary search: take a search list of length n, if the middle item is not the required item, take the upper or lower half as the search list. Exercise 25.01 Discuss with students the important characteristics of these recursive descriptions: The general case gets closer to the base case. For example, reciting the alphabet backwards: After writing z, the list of letters to be written is now one less, so eventually there will be no more letters in the list to be written, so no action is required (the base case). Get students to think of other tasks that can be described in a recursive way. (An example is eating a piece of cake: as long as there is a piece of cake, take a bite from the piece. The base case is when there is no cake left.) 25.02 Topic 2 Programming recursive subroutines Coursebook section 25.02 Programming a recursive subroutine Teaching ideas Start with examples that students found easy to understand. If they are not familiar with the factorial function, go through Worked Example 25.02 first. Go through Worked Example 25.01. Students do Task 25.01. Students answer Question 25.01 (after discussion). Go through Worked Example 25.02 and get the students to program it. Exercise 25.02 Get students to convert the following pseudocode to program code: PROCEDURE LettersBackwards(n : INTEGER) OUTPUT (CHAR(n + 64)) // n + 64 is the ASCII code of the nth letter IF n > 0 THEN CALL LettersBackwards(n-1) © Cambridge University Press 2016 ENDIF ENDPROCEDURE Students should now test their procedure with different values of n and check that their output is as expected. 25.03 Topic 3 Tracing a recursive subroutine Coursebook section 25.03 Tracing a recursive subroutine Teaching ideas It is very important to spend a good amount of time on this topic, so students really understand what is happening during recursion. Use Figure 25.06 in the coursebook to show how recursive calls are like an onion, with each layer representing a recursive call. When completing a trace table for a recursive routine, it is important to show when the ‘unwinding’ starts. So you don’ t go back up into previous rows, but add new rows to the trace table. Start with the trace table in Table 25.01 in the coursebook. Because the recursive call is at the end of the procedure CountDownFrom, there are no further statements to execute when each recursive call returns. So this produces a straightforward trace table. Dry-running the procedure CountUpTo is more complicated: there are statements to execute after returning from the recursive call, and the trace table needs to reflect that these are executed later (when the recursive calls unwind). Study the table in the coursebook (Figure 25.04) carefully. After demonstrating the tracing of the factorial function, it makes sense to ask students to complete Task 25.03. The output from this should match the trace table shown in the coursebook in Figure 25.05. Exercise 25.03 Consider the recursive version of the binary search: PROCEDURE BinarySearch(BYVAL List, BYREF First, BYREF Last, BYVAL SearchItem) Found FALSE NotInList FALSE Middle (First + Last) DIV 2 IF List[Middle] = SearchItem THEN Found TRUE // base case ELSE IF First >= Last THEN NotInList TRUE ELSE © Cambridge University Press 2016 IF List[Middle] < SearchItem THEN BinarySearch(List, Middle+1, Last, SearchItem) // general ELSE BinarySearch(List, First, Middle-1, SearchItem) // general ENDIF ENDIF ENDIF IF NotInList = TRUE THEN OUTPUT error message IF Found = TRUE THEN OUTPUT middle ENDPROCEDURE Indicate the base case and the general case in the above code. Dry-run the above code with the call BinarySearch(List, 1, 15, “Jo”) when List consists of: [Ali, Ben, Colin, Dan, Emma, Fi, Gina, Henry, Jo, Kay, Li, Mo, Ng, Oli, Pete] Call Number 1 2 3 4 First Last Middle List[Middle] Found NotInList 1 9 9 9 15 15 11 9 8 12 10 9 Henry Mo Kay Jo FALSE FALSE TRUE **Exercise 25.04 Write program code for recursive tree traversal algorithms (see Section 23.07 Binary trees). 25.04 Topic 4 Execution of a recursive subroutine Coursebook section 25.04 Running a recursive subroutine, 25.05 Benefits and drawbacks of recursion Teaching ideas It is important for students to understand that whenever a subroutine is called (recursive or not) the return address and the value of parameters and local variables (grouped together and known as a stack frame) are stored on the stack. When the subroutine is completed, the return address and the parameters and local variables are popped off the stack and restored to the running program. When subroutine calls are recursive, further return addresses and values are stored on the stack before any are popped off. If the recursion is deeply nested (many ‘onion skins’) there may not be enough space on the stack, causing stack overflow. Go through Worked Example 25.03. To make it more visual, prepare some cards, each to hold the data for one stack frame. Each time the function is called, write the © Cambridge University Press 2016 data to be pushed onto the stack on a blank card and stack up these cards on top of one another. When the function unwinds, it is easy to see which card gets popped off the stack: the one on the top. Remember partial results are also recorded on the stack frame. Exercise 25.05 Ask students to work in pairs and perform the same method for another recursive program. For example, the pseudocode in Task 25.02. Note: Exam-style question 3 is very challenging. You could get students to write the program and include output statements to give a trace of the calls. See sample solution at the end of this chapter. © Cambridge University Press 2016