Presentation is loading. Please wait.

Presentation is loading. Please wait.

© Janice Regan, CMPT 128, February. 2007 0 CMPT 128: Introduction to Computing Science for Engineering Students Recursion.

Similar presentations


Presentation on theme: "© Janice Regan, CMPT 128, February. 2007 0 CMPT 128: Introduction to Computing Science for Engineering Students Recursion."— Presentation transcript:

1 © Janice Regan, CMPT 128, February. 2007 0 CMPT 128: Introduction to Computing Science for Engineering Students Recursion

2 © Janice Regan, CMPT 128,2007-2013 1 Introduction to Recursion  Recursion:  A function that calls itself is said to be a recursive function  A function that calls itself results in direct recursion  If function A calls function B, and in turn function B calls function A this results in indirect recursion  C++, like most high-level languages, allows recursion  Recursion can result in elegant easy to understand and develop code (‘efficient’ development and maintenance)  Recursion may be less ‘efficient’ to execute than an equivalent iterative solution,

3 © Janice Regan, CMPT 128,2007-2013 2 Recursive void Functions  Recursion is based on the design technique know as ‘divide and conquer’  Divide: break the task into smaller parts  Conquer: solve a large and complex problem efficiently  When solving a problem recursively  Divide: each smaller part of the task is the same as the whole task The same algorithm or series of steps is used for the whole problem and for each smaller task the problem is divided into

4 © Janice Regan, CMPT 128,2007-2013 3 Example: quick sort  Consider large task: sort a large array into descending order  Choose pivot from ‘middle’ of array, Switch the pivot and first element in array  Sort the array into two parts, one with all numbers larger than the pivot, one with all numbers smaller than the pivot  Move the pivot back between the two parts  Subtasks must be smaller versions of original task  Subtask 1: repeat the main task on the part of the array with elements larger than the pivot  Subtask 2: repeat the main task on the part of the array with elements smaller than the pivot.  Quick sort is a method of the type that is well suited to be solved by recursion

5 © Janice Regan, CMPT 128,2007-2013 4 Recursive void Function: a simple example  Task: calculate the sum of the squares of all integers from 1 to j, for all integers j from 1 to n. Display sums of integers vertically, one line for each j, beginning with j=1  Example call: sumSqIntegers(4); Produces output: 1 5 14 30

6 © Janice Regan, CMPT 128,2007-2013 5 Sums of squares: Recursive Definition  Break problem into two cases  Base case: if n=1  Simply write number n to screen (1*1=1)  Do not call the function again  Return to the calling function (previous recursive call)  Recursive case: if n>1, two subtasks:  Calculate and print all sums for j=1,..,n-1  Calculate and print the sum for j=n  Return to the calling function

7 © Janice Regan, CMPT 128,2007-2013 6 Sums of squares: Recursive Definition  Example: argument 4:  1 st subtask calculates the sums for each j j=1,…,3 and prints them one per line 1, 5, 14 Call the function sumSqIntegers for j-1  2 nd subtask calculates the sum for j=4 and prints it on a new line, 30  Return to the calling program

8 © Janice Regan, CMPT 128,2007-2013 7 sumSqIntegers: Function Definition void sumSqIntegers(int maxInteger, int& value) { if (maxInteger == 1) { cout << maxInteger << endl; //Base case value = maxInteger; } else { sumSqIntegers(maxInteger-1, value); value += maxInteger * maxInteger; //Recursive case cout << value << endl;}

9 © Janice Regan, CMPT 128,2007-2013 8 Sums of squares: Trace (1)  Example call: sumSqIntegers(4,value); //1 st call sumSqIntegers(3,value); //2 nd call sumSqIntegers(2,value); //3 rd call sumSqIntegers(1,value); //4 th call cout << 1 << endl; //4 th call cout << 2*2 + 1 << endl; //3 rd call cout << 3*3 + 5 << endl; //2 nd call cout << 4*4 +14 << endl; //1 st call

10 © Janice Regan, CMPT 128,2007-2013 9 Sums of squares: Trace (2)  During 1 st call n=4, and the function is called for n=3 (recursive case)  During 2 nd call n=3, and the function is called for n=2 (recursive case)  During 3 rd call n=2, and the function is called for n=1 (recursive case)  During 4 th call n=1, 1is printed to the screen and the cursor moves to the next line (stopping case) then returns to 3 rd case  During the remainder of the 3 rd call n=2, 5 is printed to the screen and the cursor moves to the next line (completes recursive case) then returns to 2 nd case  During the remainder of the 2 nd call n=3, 14 is printed to the screen and the cursor moves to the next line (completes recursive case) then returns to 1 st case  During the remainder of the 1 st call n=4, 30 is printed to the screen and the cursor moves to the next line (completes recursive case) then returns to calling program

11 © Janice Regan, CMPT 128,2007-2013 10 Sums of squares: Trace (3) void sumSqIntegers(int maxInteger, int& value) { if (maxInteger == 1) { //Base case cout << maxInteger << endl; value = maxInteger; } else { //Recursive case sumSqIntegers(maxInteger-1, value); value += maxInteger * maxInteger; cout << value << endl;} 3 rd call: sumSqIntegers(1, value) 4 th call: Print 1, value=1 Calling function: sumSqIntegers(4, value) 1 st call: sumSqIntegers(3, value) 2 nd call: sumSqIntegers(2, value)

12 © Janice Regan, CMPT 128,2007-2013 11 Sums of squares: Trace (4) Calling function: sumSqIntegers(4, value) 1 st call: sumSqIntegers(3, value) 2 nd call: sumSqIntegers(2, value) 3 rd call: determine value value = 1+2*2 Print 5 void sumSqIntegers(int maxInteger, int& value) { if (maxInteger == 1) { //Base case cout << maxInteger << endl; value = maxInteger; } else { //Recursive case sumSqIntegers(maxInteger-1, value); value += maxInteger * maxInteger; cout << value << endl;}

13 © Janice Regan, CMPT 128,2007-2013 12 Sums of squares: Trace (5) Calling function: sumSqIntegers(4, value) 1 st call: sumSqIntegers(3, value) void sumSqIntegers(int maxInteger, int& value) { if (maxInteger == 1) { //Base case cout << maxInteger << endl; value = maxInteger; } else { //Recursive case sumSqIntegers(maxInteger-1, value); value += maxInteger * maxInteger; cout << value << endl;} 2 nd call: determine value value = 5 + 3*3 Print 14

14 © Janice Regan, CMPT 128,2007-2013 13 Sums of squares: Trace (6) Calling function: sumSqIntegers(4, value) void sumSqIntegers(int maxInteger, int& value) { if (maxInteger == 1) { //Base case cout << maxInteger << endl; value = maxInteger; } else { //Recursive case sumSqIntegers(maxInteger-1, value); value += maxInteger * maxInteger; cout << value << endl;} 1 st call: determine value value = 14+4*4 Print 30

15 © Janice Regan, CMPT 128,2007-2013 14 Infinite Recursion  Base case MUST eventually be entered  If there is no base case OR  If the base case is never reached  Then recursion continues for ever (or at least until memory for new function frames is exhausted)  In our example (sumSqIntegers):  Base case happened when we reached 1, the sum of the squares of integers 1,..,1 is 1  That’s when recursion stopped and we began returning up through the stack of recursive frames

16 © Janice Regan, CMPT 128,2007-2013 15 Infinite Recursion: Example  Consider alternate function definition: void altSumSqIntegers(int maxInteger, int& value) { altsumSqIntegers(maxInteger-1, value); value += maxInteger * maxInteger; cout << value << endl; }  Seems logical on the surface but there is no stopping case so recursion never stops

17 © Janice Regan, CMPT 128,2007-2013 16 Recursion: Review  A recursive function must have:  One or more recursive cases where the function accomplishes it’s task by: Making one or more recursive calls to solve smaller versions of original task  One or more base cases or stopping cases where the function accomplishes it’s task by simple calculation without recursive call

18 © Janice Regan, CMPT 128,2007-2013 17 Stacks for Recursion  A stack  Specialized memory structure  Like stack of paper Place each new page (frame) on top When you finish with one page (frame) then take the page (frame) from the top of the stack and continue  Called "last-in/first-out“ (LIFO) memory structure  Recursion uses stacks  Each recursive call placed on stack  When one completes, last call is removed from stack

19 © Janice Regan, CMPT 128,2007-2013 18 Stack Overflow  Size of stack limited  Memory is finite  Long chain of recursive calls continually adds to stack  All are added before base case causes removals  If stack attempts to grow beyond limit:  Stack overflow error  Infinite recursion always causes this

20 © Janice Regan, CMPT 128,2007-2013 19 Why Use Recursion  Recursion is not always the ‘best solution’  Some languages do not allow recursion  Any task accomplished with recursion can also be done using iteration  Recursive:  Recursion can result in elegant easy to understand and develop code (‘efficient’ development and maintenance)  Recursion may be less ‘efficient’ to execute than an equivalent iterative solution (may run slower)

21 © Janice Regan, CMPT 128,2007-2013 20 Recursive Functions can have any type  Recursion not limited to void functions  Can return value of any type  Same approach as for our original example  Let’s recast that original example so that the recursive function has type int rather than type void

22 © Janice Regan, CMPT 128,2007-2013 21 sumSqIntegers: Function Definition int sumSqIntegers(int maxInteger) { int value; if (maxInteger == 1) { cout << maxInteger << endl; //Base case return(maxInteger); } else { sumSqIntegers(maxInteger-1); value += maxInteger * maxInteger; //Recursive case cout << value << endl; return(value);}

23 © Janice Regan, CMPT 128,2007-2013 22 Sums of squares: Trace (1)  Example call: sumSqIntegers(4); //1 st call sumSqIntegers(3); //2 nd call sumSqIntegers(2); //3 rd call sumSqIntegers(1); //4 th call cout << 1 << endl; //4 th call cout << 2*2 + 1 << endl; //3 rd call cout << 3*3 + 5 << endl; //2 nd call cout << 4*4 +14 << endl; //1 st call

24 © Janice Regan, CMPT 128,2007-2013 23 Return a Value Recursion Example: Powers  Recall predefined function pow(): result = pow(2.0,3.0);  Returns 2 raised to power 3 (8.0)  Takes two double arguments  Returns double value  Let’s write recursively  For simple example

25 © Janice Regan, CMPT 128,2007-2013 24 Function Definition for power() int power(int x, int n) { if (n 0) { return (power(x, n-1)*x); } else { return (1); } }

26 © Janice Regan, CMPT 128,2007-2013 25 Calling Function power()  Larger example: power(2,3);  power(2,2)*2  power(2,1)*2  power(2,0)*2  1  Reaches base case  Recursion stops  Values "returned back" up stack

27 © Janice Regan, CMPT 128,2007-2013 26 Recursive Design Techniques  Start simple  Make sure the problem can be broken into parts that are copies of each other and the ‘whole’ problem  Define your recursive cases  Do the recursive cases return or produce the correct results  Define your stopping case or cases  When will the series of recursive calls end  Do the stopping cases return or produce the correct results  Make sure that you stop your recursive case and enter the stopping cases when conditions are correct

28 © Janice Regan, CMPT 128,2007-2013 27 Recursive design: power  Consider power() again  Can the problem be broken down into smaller parts:  x n = x i *x k where n=i+k  this problem can be broken down into parts that are equivalent to the ‘whole’ problem  Design the recursive case  power(x, n) returns: power(x, n – 1) * x  Is this correct? x n = x n-1 *x so yes  Design the stopping case  x 0 =1, x 1 =x When do we stop?  When n=0 we know the answer regardless of the value of x  So out stopping case is n=0, x 0 =1

29 © Janice Regan, CMPT 128,2007-2013 28 Recursive Design Check: power()  Can infinite recursion happen with the power() function we have designed  2 nd argument decreases by 1 each call  Eventually we will reach the base case of n=0  Does the stopping case return the correct value:  n=0 is base case which implies power(x,0)  power(x,0) returns 1, which is correct for x 0  Does the recursive case return the correct value:  For n>1, power(x,n) returns power(x,n-1)*x  x n = x n-1 *x so this is correct

30 © Janice Regan, CMPT 128,2007-2013 29 Another recursive example  Now lets return to our discussion of quick sort and see the application of recursion to that algorithm


Download ppt "© Janice Regan, CMPT 128, February. 2007 0 CMPT 128: Introduction to Computing Science for Engineering Students Recursion."

Similar presentations


Ads by Google