Prof. S.M. Lee Department of Computer Science.

Slides:



Advertisements
Similar presentations
Introduction to Recursion and Recursive Algorithms
Advertisements

Analyzing Algorithms and Problems Prof. Sin-Min Lee Department of Computer Science.
Copyright 2006 by Pearson Education 1 Building Java Programs Chapter 12: Recursion.
Lesson 19 Recursion CS1 -- John Cole1. Recursion 1. (n) The act of cursing again. 2. see recursion 3. The concept of functions which can call themselves.
C++ Programming: Program Design Including Data Structures, Third Edition Chapter 16: Recursion.
Unit 181 Recursion Definition Recursive Methods Example 1 How does Recursion work? Example 2 Problems with Recursion Infinite Recursion Exercises.
Recursive Algorithms Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Starting Out with C++: Early Objects 5/e © 2006 Pearson Education. All Rights Reserved Starting Out with C++: Early Objects 5 th Edition Chapter 14 Recursion.
Recursion A recursive function is a function that calls itself either directly or indirectly through another function. The problems that can be solved.
Copyright © 2008 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Starting Out with Java: Early Objects Third Edition by Tony Gaddis Chapter.
Prof. S.M. Lee Department of Computer Science. Answer:
Introduction to complexity Prof. Sin-Min Lee Department of Computer Science San Jose State University.
A Review of Recursion Dr. Jicheng Fu Department of Computer Science University of Central Oklahoma.
Nirmalya Roy School of Electrical Engineering and Computer Science Washington State University Cpt S 122 – Data Structures Recursion Review.
Department of Computer Science and Engineering, HKUST 1 HKUST Summer Programming Course 2008 Recursion.
Chapter 14: Recursion Starting Out with C++ Early Objects
Recursion. Basic problem solving technique is to divide a problem into smaller subproblems These subproblems may also be divided into smaller subproblems.
Lecture 8. How to Form Recursive relations 1. Recap Asymptotic analysis helps to highlight the order of growth of functions to compare algorithms Common.
C++ Programming: From Problem Analysis to Program Design, Third Edition Chapter 17: Recursion.
1 Decrease-and-Conquer Approach Lecture 06 ITS033 – Programming & Algorithms Asst. Prof. Dr. Bunyarit Uyyanonvara IT Program, Image and Vision Computing.
CS 1704 Introduction to Data Structures and Software Engineering.
© 2010 Pearson Addison-Wesley. All rights reserved. Addison Wesley is an imprint of Chapter 15: Recursion Starting Out with Java: From Control Structures.
Chapter 3 (Part 3): Mathematical Reasoning, Induction & Recursion  Recursive Algorithms (3.5)  Program Correctness (3.6)
Copyright © 2011 Pearson Education, Inc. Starting Out with Java: Early Objects Fourth Edition by Tony Gaddis Chapter 14: Recursion.
Chapter 9: Recursion1 CHAPTER 9 RECURSION. Recursion  Concept of recursion  A recursive: Benefit and Cost  Comparison : Iterative and recursive functions.
M180: Data Structures & Algorithms in Java
CHAPTER 02 Recursion Compiled by: Dr. Mohammad Omar Alhawarat.
Functions and an Introduction to Recursion.  Recursive function ◦ A function that calls itself, either directly, or indirectly (through another function)
Stephen P. Carl - CS 2421 Recursion Reading : Chapter 4.
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.
Computer Science and Software Engineering University of Wisconsin - Platteville 9. Recursion Yan Shi CS/SE 2630 Lecture Notes Partially adopted from C++
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
Review Introduction to Searching External and Internal Searching Types of Searching Linear or sequential search Binary Search Algorithms for Linear Search.
1 TCSS 143, Autumn 2004 Lecture Notes Recursion Koffman/Wolfgang Ch. 7, pp ,
Recursion. What is recursion? Rules of recursion Mathematical induction The Fibonacci sequence Summary Outline.
Dale Roberts CSCI N305 Functions Recursion Department of Computer and Information Science, School of Science, IUPUI.
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.
IB Computer Science Unit 5 – Advanced Topics Recursion.
Recursion.
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.
Chapter 11Java: an Introduction to Computer Science & Programming - Walter Savitch 1 Chapter 11 l Basics of Recursion l Programming with Recursion Recursion.
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.
Recursion A function is said to be recursive if it calls itself, either directly or indirectly. void repeat( int n ) { cout
Recursion. What is recursion? smaller version Sometimes, the best way to solve a problem is by solving a smaller version of the exact same problem first.
Chapter 15: Recursion. Recursive Definitions Recursion: solving a problem by reducing it to smaller versions of itself – Provides a powerful way to solve.
JAVA: An Introduction to Problem Solving & Programming, 7 th Ed. By Walter Savitch ISBN © 2015 Pearson Education, Inc., Upper Saddle River,
Chapter 15: Recursion. Objectives In this chapter, you will: – Learn about recursive definitions – Explore the base case and the general case of a recursive.
Program Development and Design Using C++, Third Edition
Section Recursion  Recursion – defining an object (or function, algorithm, etc.) in terms of itself.  Recursion can be used to define sequences.
CSC 143 P 1 CSC 143 Recursion [Chapter 5]. CSC 143 P 2 Recursion  A recursive definition is one which is defined in terms of itself  Example:  Compound.
Lecture 11 Recursion. A recursive function is a function that calls itself either directly, or indirectly through another function; it is an alternative.
Recursion Data Structure Submitted By:- Dheeraj Kataria.
Introduction to Algorithms
Chapter Topics Chapter 16 discusses the following main topics:
Chapter 15 Recursion.
RECURSION.
Decrease-and-Conquer Approach
Chapter 15 Recursion.
Java 4/4/2017 Recursion.
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Recursion "To understand recursion, one must first understand recursion." -Stephen Hawking.
Applied Algorithms (Lecture 17) Recursion Fall-23
Recursion Chapter 11.
Recursion Data Structures.
Functions Recursion CSCI 230
Module 1-10: Recursion.
Introduction to Algorithms
Yan Shi CS/SE 2630 Lecture Notes
Presentation transcript:

Prof. S.M. Lee Department of Computer Science

Recursion Recursion is more than just a programming technique. It has two other uses in computer science and software engineering, namely: as a way of describing, defining, or specifying things. as a way of designing solutions to problems (divide and conquer).

Mathematical Examples factorial function factorial(0) = 1 factorial(n) = n * factorial(n-1) [for n>0] Let's compute factorial(3). factorial(3) = 3 * factorial(2) = 3 * ( 2 * factorial(1) ) = 3 * ( 2 * ( 1 * factorial(0) )) = 3 * ( 2 * ( 1 * 1 ) )) = 6

Fibonacci function: fibonacci(0) = 1 fibonacci(1) = 1 fibonacci(n) = fibonacci(n-1) + fibonacci(n-2) [for n>1] This definition is a little different than the previous ones because It has two base cases, not just one; in fact, you can have as many as you like. In the recursive case, there are two recursive calls, not just one. There can be as many as you like.

Recursion Recursion can be seen as building objects from objects that have set definitions. Recursion can also be seen in the opposite direction as objects that are defined from smaller and smaller parts. “Recursion is a different concept of circularity.”(Dr. Britt, Computing Concepts Magazine, March 97, pg.78)

Suppose that we have a series of functions for finding the power of a number x. pow0(x) = 1 pow1(x) = x = x * pow0(x) pow2(x) = x * x = x * pow1(x) pow3(x) = x * x * x = x * pow2(x) We can turn this into something more usable by creating a variable for the power and making the pattern explicit: pow(0,x) = 1 pow(n,x) = x * pow(n-1,x) Finding the powers of numbers

For instance: 2**3 = 2 * 2**2 = 2 * 4 = 8 2**2 = 2 * 2**1 = 2 * 2 = 4 2**1 = 2 * 2**0 = 2 * 1 = 2 2**0 = 1

Almost all programming languages allow recursive functions calls. That is they allow a function to call itself. And some languages allow recursive definitions of data structures. This means we can directly implement the recursive definitions and recursive algorithms that we have just been discussing. For example, the definition of the factorial function factorial(0) = 1 factorial(n) = n * factorial(n-1) [ for n > 0 ]. can be written in C without the slightest change: int factorial(int n) { if (n == 0) return 1 ; else return n * factorial(n-1) ; }

Basic Recursion What we see is that if we have a base case, and if our recursive calls make progress toward reaching the base case, then eventually we terminate. We thus have our first two fundamental rules of recursion:

Basic Recursion 1. Base cases: –Always have at least one case that can be solved without using recursion. 2. Make progress: –Any recursive call must make progress toward a base case.

Euclid's Algorithm In Euclid's 7th book in the Elements series (written about 300BC), he gives an algorithm to calculate the highest common factor (largest common divisor) of two numbers x and y where (x < y). This can be stated as: 1.Divide y by x with remainder r. 2.Replace y by x, and x with r. 3.Repeat step 1 until r is zero. When this algorithm terminates, y is the highest common factor.

GCF(34,017 and 16,966). Euclid's algorithm works as follows: 34,017/16,966 produces a remainder 85 16,966/85 produces a remainder 51 85/51 produces a remainder 34 51/34 produces a remainder 17 34/17 produces a remainder 0 and the highest common factor of 34,017 and 16,966 is 17.

Euclid's algorithm involves several elements: simple arithmetic operations (calculating the remainder after division), comparison of a number against 0 (test), and the ability to repeatedly execute the same set of instructions (loop). and any computer programming language has these basic elements. The design of an algorithm to solve a given problem is the motivation for a lot of research in the field of computer science.

Euclid's Algorithm Euclid's Algorithm determines the greatest common divisor of two natural numbers a, b. That is, the largest natural number d such that d | a and d | b. GCD(33,21)=3 33 = 1* = 1* = 1* = 3*3

The main benefits of using recursion as a programming technique are these: invariably recursive functions are clearer, simpler, shorter, and easier to understand than their non-recursive counterparts. the program directly reflects the abstract solution strategy (algorithm). From a practical software engineering point of view these are important benefits, greatly enhancing the cost of maintaining the software.

Main disadvantage of programming recursively The main disadvantage of programming recursively is that, while it makes it easier to write simple and elegant programs, it also makes it easier to write inefficient ones. when we use recursion to solve problems we are interested exclusively with correctness, and not at all with efficiency. Consequently, our simple, elegant recursive algorithms may be inherently inefficient.

Consider the following program for computing the fibonacci function. int s1, s2 ; int fibonacci (int n) { if (n == 0) return 1; else if (n == 1) return 1; else { s1 = fibonacci(n-1); s2 = fibonacci(n-2); return s1 + s2; }

The main thing to note here is that the variables that will hold the intermediate results, S1 and S2, have been declared as global variables. This is a mistake. Although the function looks just fine, its correctness crucially depends on having local variables for storing all the intermediate results. As shown, it will not correctly compute the fibonacci function for n=4 or larger. However, if we move the declaration of s1 and s2 inside the function, it works perfectly. This sort of bug is very hard to find, and bugs like this are almost certain to arise whenever you use global variables to storeintermediate results of a recursive function.

Recursion is based upon calling the same function over and over, whereas iteration simply `jumps back' to the beginning of the loop. A function call is often more expensive than a jump.

The overheads that may be associated with a function call are: Space: Every invocation of a function call may require space for parameters and local variables, and for an indication of where to return when the function is finished. Typically this space (allocation record) is allocated on the stack and is released automatically when the function returns. Thus, a recursive algorithm may need space proportional to the number of nested calls to the same function.

Time: The operations involved in calling a function - allocating, and later releasing, local memory, copying values into the local memory for the parameters, branching to/returning from the function - all contribute to the time overhead.

If a function has very large local memory requirements, it would be very costly to program it recursively. But even if there is very little overhead in a single function call, recursive functions often call themselves many many times, which can magnify a small individual overhead into a very large cumulative overhead.

int factorial(int n) { if (n == 0) return 1; else return n * factorial(n-1); } There is very little overhead in calling this function, as it has only one word of local memory, for the parameter n. However, when we try to compute factorial(20), there will end up being 21 words of memory allocated - one for each invocation of the function:

factorial(20) -- allocate 1 word of memory, call factorial(19) -- allocate 1 word of memory, call factorial(18) -- allocate 1 word of memory,. call factorial(2) -- allocate 1 word of memory, call factorial(1) -- allocate 1 word of memory, call factorial(0) -- allocate 1 word of memory, at this point 21 words of memory

and 21 activation records have been allocated. return release 1 word of memory. return 1*1. -- release 1 word of memory. return 2*1. -- release 1 word of memory.

Iteration as a special case of recursion The first insight is that iteration is a special case of recursion. void do_loop () { do {... } while (e); } is equivalent to: void do_loop () {... ; if (e) do_loop(); } A compiler can recognize instances of this form of recursion and turn them into loops or simple jumps. E.g.: void do_loop () { start:...; if (e) goto start; } Notice that this optimization also removes the space overhead associated with function calls.

Most recursive algorithms can be translated, by a fairly mechanical procedure, into iterative algorithms. Sometimes this is very straightforward - for example, most compilers detect a special form of recursion, called tail recursion, and automatically translate into iteration without your knowing. Sometimes, the translation is more involved: for example, it might require introducing an explicit stack with which to `fake' the effect of recursive calls.

{Non-recursive version of Power function} FUNCTION PowerNR (Base : real; Exponent : integer) : real; {Preconditions: Exponent >= 0} {Accepts Base and exponent values} {Returns Base to the Exponent power} VAR Count : integer; {Counts number of times BAse is multiplied} Product : real; {Holds the answer as it is being calculated} BEGIN Product := 1; FOR Count := 1 TO Exponent DO Product := Product * Base; PowerNR := Product END; {PowerNR}

We have seen one form of circularity already in our classes, with a For loop. Int x; For (x=0; x<=10; x++) { cout<<x; }

Problems solving used loops In a for loop, we have a set loop structure which controls the length of the repetition. Many problems solved using loops may be solved using a recursion. In recursion, problems are defined in terms of smaller versions of themselves.

Power function There are recursive definitions for many mathematical problems: The function Power (used to raise the number y to the xth power). Assume x is a non-negative integer: Y^x = 1 if x is 0; otherwise, Y*Y^(x-1)

Power Function 2^3 = 2*2^2 = 2 * 4 = 8 2^2 = 2*2^1 = 2 * 2 = 4 2^1 = 2*2^0= 2 * 1 = 2 2^0 = 1

Factorial Function The factorial function has a natural recursive definition: n!= 1, if n = 0 or if n = 1; otherwise, n! = n * (n - 1)!

For example: 5! = 5*4! = 5*24 4! = 4*3! = 4*6 3! = 3*2! = 3*2 2! = 2*1! = 2*1 1! = 1

Excessive Recursion When a program runs too deep: When a simple loop runs more efficiently: Fibonacci sequence:

Ackermann’s Function “…one of the fastest growing non-primitive recursive functions. Faster growing than any primitive recursive function.” It grows from 0 to 2^65546 in a few breaths.

Basis for Ackermann’s If A(0, n)=n+1, by definition If A(m, 0)=A(m-1, 1) else, A(m, n)=A(m-1, A(m, n-1))… …until A(0, A(1, A(…m-2, n-1)))…back to definition

Example A(2, 2)=A(1, A(2, 1))=A(0, A(1, A(2, 1))) …=A(1, A(2, 1))+1=A(0, A(1, A(2, 0)))+1 …=A(1, A(1, 1))+2=A(0, A(1, A(1, 0))) …=A(1, A(0, 1))+3=A(0, A(0, 0))+5=7!!!

Shortcuts: If A(0, n)=n+1 If A(1, n)=n+2 If A(2, n)=2n+3 If A(3, n)=2^n+3 If A(4, n)=2^(n+3)*2 If A(5, n)=TOO MUCH!!!!!

A(4, 1)=13 A(4, 2)=65533 A(4, 3)=2^ A(4, 4)=2^(2^(65536)-3)

“Ackermann’s function is a form of meta- multiplication.”Dr. Forb. a+b=adding the operand a*b=adding the operand “a” to itself b times a^b=multiplying the operand “a” by itself b times b b times