Recursion Self-Referencing Functions. Problem # 1 Write a function that, given n, computes n! n! == 1 2... (n-1) n n! == 1  2 ...  (n-1)  nExample:

Slides:



Advertisements
Similar presentations
Basics of Recursion Programming with Recursion
Advertisements

New Mexico Computer Science For All
Recursion CS /02/05 L7: Files Slide 2 Copyright 2005, by the authors of these slides, and Ateneo de Manila University. All rights reserved Iteration.
RECURSION Self referential functions are called recursive (i.e. functions calling themselves) Recursive functions are very useful for many mathematical.
Computer Science 1620 Functions. Given a number n, the factorial of n, written n!, is computed as follows: note: 0! = 1 examples: n! = n x (n-1) x (n-2)
Chapter 10 Recursion. Copyright © 2005 Pearson Addison-Wesley. All rights reserved Chapter Objectives Explain the underlying concepts of recursion.
1 Chapter 18 Recursion Dale/Weems/Headington. 2 Chapter 18 Topics l Meaning of Recursion l Base Case and General Case in Recursive Function Definitions.
Recursive Algorithms Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
ICS103 Programming in C Lecture 11: Recursive Functions
Algorithm Analysis CS 201 Fundamental Structures of Computer Science.
28-Jun-15 Recursion. 2 Definitions I A recursive definition is a definition in which the thing being defined occurs as part of its own definition Example:
Chapter 15 Recursive Algorithms. 2 Recursion Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
Recursion. Idea: Some problems can be broken down into smaller versions of the same problem Example: n! 1*2*3*…*(n-1)*n n*factorial of (n-1)
Unit 7 1 Unit 7: Recursion H Recursion is a fundamental programming technique that can provide an elegant solution to a certain kinds of problems H In.
Recursion In general there are two approaches to writing repetitive algorithms. One uses loops(while, do while and for): the other uses recursion. Recursion.
CS Discrete Mathematical Structures Mehdi Ghayoumi MSB rm 132 Ofc hr: Thur, 9:30-11:30a.
1 Chapter 18-1 Recursion Dale/Weems. 2 Chapter 18 Topics l Meaning of Recursion l Base Case and General Case in Recursive Function Definitions l Writing.
A Review of Recursion Dr. Jicheng Fu Department of Computer Science University of Central Oklahoma.
Department of Computer Science and Engineering, HKUST 1 HKUST Summer Programming Course 2008 Recursion.
1 Recursion Algorithm Analysis Standard Algorithms Chapter 7.
Recursion A method is recursive if it makes a call to itself. A method is recursive if it makes a call to itself. For example: For example: public void.
Recursion l Powerful Tool l Useful in simplifying a problem (hides details of a problem) l The ability of a function to call itself l A recursive call.
CHAPTER 02 Recursion Compiled by: Dr. Mohammad Omar Alhawarat.
Slides prepared by Rose Williams, Binghamton University ICS201 Lecture 19 : Recursion King Fahd University of Petroleum & Minerals College of Computer.
RecursionRecursion Recursion You should be able to identify the base case(s) and the general case in a recursive definition To be able to write a recursive.
Recursion Textbook chapter Recursive Function Call a recursive call is a function call in which the called function is the same as the one making.
Introduction to algorithm design and recursion CS125 Spring 2007 Arthur Kantor.
1 7.Algorithm Efficiency What to measure? Space utilization: amount of memory required  Time efficiency: amount of time required to process the data Depends.
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
Reading – Chapter 10. Recursion The process of solving a problem by reducing it to smaller versions of itself Example: Sierpinski’s TriangleSierpinski’s.
JAVA Advanced Control Structures. Objectives Be able to use a switch statement for selective execution. Be able to implement repetition using alternative.
Review Introduction to Searching External and Internal Searching Types of Searching Linear or sequential search Binary Search Algorithms for Linear Search.
Chapter 13 Recursion. Learning Objectives Recursive void Functions – Tracing recursive calls – Infinite recursion, overflows Recursive Functions that.
Chapter 4 Recursion. Copyright © 2004 Pearson Addison-Wesley. All rights reserved.1-2 Chapter Objectives Explain the underlying concepts of recursion.
1 7.Algorithm Efficiency What to measure? Space utilization: amount of memory required  Time efficiency: amount of time required to process the data.
Recursion. What is recursion? Rules of recursion Mathematical induction The Fibonacci sequence Summary Outline.
Data Structures R e c u r s i o n. Recursive Thinking Recursion is a problem-solving approach that can be used to generate simple solutions to certain.
©TheMcGraw-Hill Companies, Inc. Permission required for reproduction or display. Chapter 15 * Recursive Algorithms.
Recursion A function that calls itself. Recursion A function which calls itself is said to be recursive. Recursion is a technique which will allow us.
Lecture 7. Solution by Substitution Method T(n) = 2 T(n/2) + n Substitute n/2 into the main equation 2T(n/2) = 2(2(T(n/4)) + n/2) = 4T(n/4) + n And T(n)
Recursion Unit 15. Recursion: Recursion is defined as the process of a subprogram calling itself as part of the solution to a problem. It is a problem.
October 3, 2001CSE 373, Autumn Mathematical Background Exponents X A X B = X A+B X A / X B = X A-B (X A ) B = X AB X N +X N = 2X N 2 N +2 N = 2 N+1.
Chapter 15: Recursion. Objectives In this chapter, you will: – Learn about recursive definitions – Explore the base case and the general case of a recursive.
W1-1 University of Washington Computer Programming I Recursion © 2000 UW CSE.
Concepts of Algorithms CSC-244 Unit 5 and 6 Recursion Shahid Iqbal Lone Computer College Qassim University K.S.A.
Chapter 15: Recursion. Recursive Definitions Recursion: solving a problem by reducing it to smaller versions of itself – Provides a powerful way to solve.
Chapter 15: Recursion. Objectives In this chapter, you will: – Learn about recursive definitions – Explore the base case and the general case of a recursive.
Copyright © 2014, 2008 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with C++ Early Objects Eighth Edition by Tony Gaddis,
Lecture 11 Recursion. A recursive function is a function that calls itself either directly, or indirectly through another function; it is an alternative.
Ms N Nashandi Dr SH Nggada Week 08 – Recursion. Outline We shall be covering the following What is a recursion? Iteration versus Recursion. Recursion.
Recursion ● Recursion or Iteration ● A Common Recursive Design Pattern ● Computing factorials ● Searching a filesystem tree ● Faster exponentiation ● Slow.
Recursion Powerful Tool
Sections 4.1 & 4.2 Recursive Definitions,
Recursion The programs discussed so far have been structured as functions that invoke one another in a disciplined manner For some problems it is useful.
Chapter 15 Recursion.
Lesson #6 Modular Programming and Functions.
More on Recursive Recursion vs. Iteration Why Recursion?
Chapter 15 Recursion.
Java 4/4/2017 Recursion.
Recursion "To understand recursion, one must first understand recursion." -Stephen Hawking.
Recursion Data Structures.
CS 201 Fundamental Structures of Computer Science
Module 1-10: Recursion.
Yan Shi CS/SE 2630 Lecture Notes
Dr. Sampath Jayarathna Cal Poly Pomona
Algorithms An algorithm is a set of instructions used to solve a specific problem In order to be useful, an algorithm must have the following properties:
Main() { int fact; fact = Factorial(4); } main fact.
Self-Referencing Functions
Recursion.
Presentation transcript:

Recursion Self-Referencing Functions

Problem # 1 Write a function that, given n, computes n! n! == (n-1) n n! == 1  2 ...  (n-1)  nExample: 5! == == 120 5! == 1  2  3  4  5 == 120Specification: Receive:n, an integer. Precondition: n >= 0 (0! == 1 && 1! == 1). Return: n!, a double (to avoid integer overflow).

Preliminary Analysis At first glance, this is a counting problem, so we could solve it with a for loop: double Factorial(int n) { double result = 1.0; for (int i = 2; i <= n; i++) result *= i; return result; } But let’s instead learn a different approach...

Analysis Consider: n! == (n-1) n Consider: n! == 1  2 ...  (n-1)  n so:(n-1)!== (n-1) so:(n-1)!== 1  2 ...  (n-1) subsituting: n!== (n-1)! n subsituting: n!== (n-1)!  n We have defined the ! function in terms of itself. Historically, this is how the function was defined before computers (and for-loops) existed.

Recursion A function that is defined in terms of itself is called self- referential, or recursive. Recursive functions are designed in a 3-step process: 1. Identify a base case -- an instance of the problem whose solution is trivial. Example: The factorial function has two base cases: if n == 0: n! == 1 if n == 1: n! == 1

Induction Step 2. Identify an induction step -- a means of solving the non-trivial (or “big”) instances of the problem using one or more “smaller” instances of the problem. Example: In the factorial problem, we solve the “big” problem using a “smaller” version of the problem: n! == n n! == (n-1)!  n 3. Form an algorithm from the base case and induction step.

Algorithm // Factorial(n) 0. Receive n. 1. If n > 1: Return Factorial(n-1) * n. Else Return 1.

Discussion The scope of a function begins at its prototype (or heading) and ends at the end of the file. Since the body of a function lies within its scope, nothing prevents a function from calling itself.

Coding /* Factorial(n), defined recursively *... */ double Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1.0; }

Behavior Suppose the function is called with n == 4. int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; }

Behavior The function starts executing, with n == 4. int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4)

Behavior The if executes, and n (4) > 1,... int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4)

Behavior and computing the return-value calls Factorial(3). int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4)

Behavior This begins a new execution, in which n == 3. int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3)

Behavior Its if executes, and n (3) > 1,... int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3)

Behavior and computing its return-value calls Factorial(2). int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3)

Behavior This begins a new execution, in which n == 2. int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3) n 2 return ? Factorial(2)

Behavior Its if executes, and n (2) > 1,... int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3) n 2 return ? Factorial(2)

Behavior and computing its return-value calls Factorial(1). int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3) n 2 return ? Factorial(2)

Behavior This begins a new execution, in which n == 1. int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3) n 2 return ? Factorial(2) n 1 return ? Factorial(1)

Behavior The if executes, and the condition n > 1 is false,... int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3) n 2 return ? Factorial(2) n 1 return ? Factorial(1)

Behavior so its return-value is computed as 1 (the base case) int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3) n 2 return ? Factorial(2) n 1 return 1 Factorial(1)

Behavior Factorial(1) terminates, returning 1 to Factorial(2). int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3) n 2 return ? Factorial(2) n 1 return 1 = 1 * 2

Behavior Factorial(2) resumes, computing its return-value: int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3) n 2 return 2 Factorial(2) = 1 * 2

Behavior Factorial(2) terminates, returning 2 to Factorial(3): int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return ? Factorial(3) n 2 return 2 = 2 * 3

Behavior Factorial(3) resumes, and computes its return-value: int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return 6 Factorial(3) = 2 * 3

Behavior Factorial(3) terminates, returning 6 to Factorial(4): int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return ? Factorial(4) n 3 return 6 = 6 * 4

Behavior Factorial(4) resumes, and computes its return-value: int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return 24 Factorial(4) = 6 * 4

Behavior Factorial(4) terminates, returning 24 to its caller. int Factorial(int n) { if (n > 1) return Factorial(n-1) * n; else return 1; } n 4 return 24 Factorial(4)

Discussion If we time the for-loop version and the recursive version, the for-loop version will usually win, because the overhead of a function call is far more time-consuming than the time to execute a loop. However, there are problems where the recursive solution is more efficient than a corresponding loop-based solution.

Problem # 2 Consider the exponentiation problem: Given two values x and n, compute x n. Example: 3 3 == 27 Specification: Receive: x, n, two numbers. Precondition: n >= 0 (for simplicity) && n is a whole number. Return: x raised to the power n.

Analysis The loop-based solution requires n “steps” (trips through the loop) to solve the problem: The loop-based solution requires  n “steps” (trips through the loop) to solve the problem: double Power(double x, int n) { double result = 1.0; for (int i = 1; i <= n; i++) result *= x; return result; } There is a faster recursive solution.

Analysis (Ct’d) How do we perform exponentiation recursively? Base case: n == 0 Return 1.0.  Return 1.0.

Analysis (Ct’d) Induction step: n > 0 We might recognize that x n == x x... x x // n factors of x x n == x  x ...  x  x // n factors of xand x n-1 == x x... x // n-1 factors of x x n-1 == x  x ...  x // n-1 factors of x and so perform a substitution: Return Power(x, n-1) * x.  Return Power(x, n-1) * x. However, this requires n “steps” (recursive calls), which is no better than the loop version. However, this requires  n “steps” (recursive calls), which is no better than the loop version.

Analysis (Ct’d) Induction-step: n > 0. Instead, we again begin with x n == x x... x x // n factors of x x n == x  x ...  x  x // n factors of x but note that x n/2 == x... x // n/2 factors of x x n/2 == x ...  x // n/2 factors of x and then recognize that when n is even: x n == x n/2 x n/2 x n == x n/2  x n/2 while when n is odd: x n == x x n/2 x n/2 x n == x  x n/2  x n/2

Analysis (Ct’d) Induction step: n > 0. We can avoid computing x n/2 twice by doing it once, storing the result, and using the stored value: a. Compute partialResult = Power(x, n/2); b. If x is even: b. If x is even: Return partialResult * partialResult. Else Return x * partialResult * partialResult. End if. This version is significantly faster than the loop-based version of the function, as n gets larger.

Algorithm 0. Receive x, n. 1. If n == 0: Return 1.0; Else a. Compute partialResult = Power(x, n/2); b. if n is even: Return partialResult * partialResult; else else Return x * partialResult * partialResult; end if. end if.

Coding We can then code this algorithm as follows: double Power(double x, int n) { if (n == 0) return 1.0; else { double partialResult = Power(x, n/2); if (n % 2 == 0) return partialResult * partialResult; else return x * partialResult * partialResult; } } which is quite simple, all things considered...

How Much Faster? How many “steps” (recursive calls) in this version? Power(x, i)i StepsSteps (loop version) (this version) (loop version) (this version) Power(x, 0)0 0 0 Power(x, 1)1 1 1 Power(x, 2)2 2 2 Power(x, 4)4 4 3 Power(x, 8)8 8 4 Power(x, 16) Power(x, 32) Power(x, n)n n Power(x, n)n n log 2 (n)+1

How Much Faster? (Ct’d) The larger n is, the better this version performs: Power(x, i)i StepsSteps (loop version) (this version) (loop version) (this version) Power(x, 1024) Power(x, 2048) Power(x, 4096) Power(x, 8192) The obvious way to solve a problem may not be the most efficient way!

Summary A function that is defined in terms of itself is called a recursive function. To solve a problem recursively, you must be able to identify a base case, and an induction step. Determining how efficiently an algorithm solves a problem is an area of computer science known as analysis of algorithms. Analysis of algorithms measures the time of an algorithm in terms of abstract “steps”, as opposed to specific statements.