Recursion - PowerPoint PPT Presentation

1 / 41
About This Presentation



Recursion CS 3358 Data Structures – PowerPoint PPT presentation

Number of Views:108
Avg rating:3.0/5.0
Slides: 42
Provided by: Penel94


Transcript and Presenter's Notes

Title: Recursion

  • CS 3358 Data Structures

Big Picture
  • Our objective is to write a recursive program and
    convince ourselves it is correct with the minimum
    amount of effort.
  • We will put some faith in the principles of
    mathematical induction as we write the program
  • We will then check the program with a small,
    non-trivial example
  • Anything that can be done with a loop, you can do
    recursively, but its certainly not appropriate
    in many cases.
  • Does it cause more or less work?

What is recursion?
  • Sometimes, the best way to solve a problem is by
    solving a smaller version of the exact same
    problem first
  • Recursion is a technique that solves a problem by
    solving a smaller problem of the same type

When you turn this into a program, you end up
with functions that call themselves (recursive
  • int f(int x)
  • int y
  • if(x0)
  • return 1
  • else
  • y 2 f(x-1)
  • return y1

All Odd Numbers are Prime
  • How a physicist determines that all odd numbers
    are prime
  • 3, 5, 7 are all prime, 9 experimental error,
    11, 13 are prime they must all be prime
  • How a business major determines that all odd
    numbers are prime
  • 3, 5, 7, 9, 11, are all prime they must all be

The Danger With Testing
  • It takes a long time to test a recursive program,
    and its easy to make mistakes along the way
  • //This code doesnt work!!
  • bool isPrime(int x)
  • if (x 3)
  • return true
  • else if (isPrime(x-2))
  • return true
  • else
  • return false

Problems defined recursively
  • There are many problems whose solution can be
    defined recursively
  • Example n! (n factorial)

1 if n 0 n! (recursive
solution) (n-1)!n if n gt 0
1 if n 0 n! (closed form
solution) 123(n-1)n if n gt 0
Coding the factorial function
  • Recursive implementation
  • int Factorial(int n)
  • if (n0) // base case
  • return 1
  • else
  • return n Factorial(n-1)

(No Transcript)
Coding the factorial function (cont.)
  • Iterative implementation
  • int Factorial(int n)
  • int fact 1
  • for(int count 2 count lt n count)
  • fact fact count
  • return fact

Divide and Conquer
  • Recursion works because mathematical induction
    works. Have faith. Or.
  • Imagine that I have lots of very similar
  • int fact(int n)
  • if (n lt 2) return 1
  • else return n fact2(n-1)
  • int fact2(int n)
  • if (n lt 2) return 1
  • else return n fact3(n-1)
  • // etc, etc.

The Machine is Dumb
  • The computer does not realize that the function
    is calling itself!
  • The computer cannot distinguish between fact
    calling fact, and fact calling fact2
  • After all, the machine code for fact and the
    machine code for fact2 are identical
  • So, if we could just become as dumb as the
    computer, recursion would not be confusing.

How is recursion implemented?
  • What happens when a function gets called?
  • int a(int w)
  • return ww
  • int b(int x)
  • int z,y
  •   // other statements
  • z a(x) y
  • return z

What happens when a function is called? (cont.)
  • An activation record is stored into a stack
    (run-time stack)
  • The computer has to stop executing function b and
    starts executing function a
  • Since it needs to come back to function b later,
    it needs to store everything about function b
    that is going to need (x, y, z, and the place to
    start executing upon return)
  • Then, x from a is bounded to w from b
  • Control is transferred to function a

What happens when a function is called? (cont.)
  • After function a is executed, the activation
    record is popped out of the run-time stack
  • All the old values of the parameters and
    variables in function b are restored and the
    return value of function a replaces a(x) in the
    assignment statement

What happens when a recursive function is called?
  • Except the fact that the calling and called
    functions have the same name, there is really no
    difference between recursive and nonrecursive
  • int f(int x)
  • int y
  • if(x0)
  • return 1
  • else
  • y 2 f(x-1)
  • return y1

Another example n choose k (combinations)
  • Given n things, how many different sets of size k
    can be chosen?
  • n n-1 n-1
  • , 1 lt k lt n (recursive solution)
  • k k k-1
  • n n!
  • , 1 lt k lt n (closed-form solution)
  • k k!(n-k)!
  • with base cases
  • n n
  • n (k 1), 1 (k n)
  • 1 n

n choose k (combinations)
  • int Combinations(int n, int k)
  • if(k 1) // base case 1
  • return n
  • else if (n k) // base case 2
  • return 1
  • else
  • return(Combinations(n-1, k)
    Combinations(n-1, k-1))

(No Transcript)
Recursion vs. iteration
  • Iteration can be used in place of recursion
  • An iterative algorithm uses a looping construct
  • A recursive algorithm uses a branching structure
  • Recursive solutions are often less efficient, in
    terms of both time and space, than iterative
  • Recursion can simplify the solution of a problem,
    often resulting in shorter, more easily
    understood source code

Termination, Stack Depth and Efficiency
  • We should always check to ensure our recursive
    programs terminate.
  • We should avoid programs that have lots of
    activation records on the stack at the same time
    (the stack depth)
  • The time required for most recursive programs is
    proportional to the number of recursive calls

How do I write a recursive function?
  • Determine the size factor
  • Determine the base case(s)
  • (the one for which you know the answer)
  • Determine the general case(s)
  • (the one where the problem is expressed as a
    smaller version of itself)
  • Verify the algorithm
  • (use the "Three-Question-Method")

Three-Question Verification Method
  • The Base-Case Question
  • Is there a nonrecursive way out of the function,
    and does the routine work correctly for this
    "base" case? 
  • The Smaller-Caller Question
  • Does each recursive call to the function involve
    a smaller case of the original problem, leading
    inescapably to the base case? 
  • The General-Case Question
  • Assuming that the recursive call(s) work
    correctly, does the whole function work

Step 1 Identify Your Base Case
  • A base case is an input value (or set of values)
    for which
  • Determining the result of our function is
    trivially easy
  • All other values can ultimately be reduced to
    (one of) our base case(s) through a finite
    sequence of decompositions

Base Case Examples
  • Factorial and Fibonacci n lt 2
  • Sorting n lt 2 (either array has 1 element or it
    has no elements at all)
  • Towers of Hanoi n 1 (exactly one ring)
  • Making Change The amount of change is exactly
    the same monetary value as a single coin

Step 2 Pick a Decomposition
  • It may take us a couple of tries to get the
    decomposition right, but we have to start
  • The decomposition must
  • Reduce the problem to a smaller problem
  • Result in eventually reaching the base case
  • Somehow be useful to solving the original problem

Example Decompositions
  • Subtract one from n (and compute n-1 factorial)
  • Divide the array in half (and sort each half)
  • Skip the first number (and compute the mean of
    the remaining elements)???

Recursive binary search
  • Non-recursive implementation
  • templateltclass ItemTypegt
  • void SortedTypeltItemTypegtRetrieveItem(ItemType
    item, bool found)
  • int midPoint
  • int first 0
  • int last length - 1
  • found false
  • while( (first lt last) !found)
  • midPoint (first last) / 2
  • if (item lt infomidPoint)
  • last midPoint - 1
  • else if(item gt infomidPoint)
  • first midPoint 1
  • else
  • found true
  • item infomidPoint

Recursive binary search (contd)
  • What is the size factor?
  • The number of elements in (infofirst ...
  • What is the base case(s)?
  • (1) If first gt last, return false
  • (2) If iteminfomidPoint, return true
  • What is the general case?
  • if item lt infomidPoint search the first half
  • if item gt infomidPoint, search the second half

Recursive binary search (contd)
  • templateltclass ItemTypegt
  • bool BinarySearch(ItemType info, ItemType
    item, int first, int last)
  • int midPoint
  • if(first gt last) // base case 1
  • return false
  • else
  • midPoint (first last)/2
  • if(item lt infomidPoint)
  • return BinarySearch(info, item, first,
  • else if (item infomidPoint) // base
    case 2
  • item infomidPoint
  • return true
  • else
  • return BinarySearch(info, item,
    midPoint1, last)

Recursive binary search (contd)
  • templateltclass ItemTypegt
  • void SortedTypeltItemTypegtRetrieveItem
    (ItemType item, bool found)
  • found BinarySearch(info, item, 0,

Recursive InsertItem (sorted list)
Recursive InsertItem (sorted list)
  • What is the size factor?
  • The number of elements in the current list
  • What is the base case(s)?
  • If the list is empty, insert item into the empty
  • If item lt location-gtinfo, insert item as the
    first node in the current list
  • What is the general case?
  • Insert(location-gtnext, item)

Recursive InsertItem (sorted list)
  • template ltclass ItemTypegt
  • void Insert(NodeTypeltItemTypegt location,
    ItemType item)
  • if(location NULL) (item lt
    location-gtinfo)) // base cases
  • NodeTypeltItemTypegt tempPtr location
  • location new NodeTypeltItemTypegt
  • location-gtinfo item
  • location-gtnext tempPtr
  • else
  • Insert(location-gtnext, newItem) //
    general case
  • template ltclass ItemTypegt
  • void SortedTypeltItemTypegtInsertItem(ItemType
  • Insert(listData, newItem)

- No "predLoc" pointer is needed for insertion
Recursive DeleteItem (sorted list)
Recursive DeleteItem (sorted list) (cont.)
  • What is the size factor?
  • The number of elements in the list
  • What is the base case(s)?
  • If item location-gtinfo, delete node pointed
    by location
  • What is the general case? 
  • Delete(location-gtnext, item)

Recursive DeleteItem (sorted list) (cont.)
  • template ltclass ItemTypegt
  • void Delete(NodeTypeltItemTypegt location,
    ItemType item)
  • if(item location-gtinfo))
  • NodeTypeltItemTypegt tempPtr location
  • location location-gtnext
  • delete tempPtr
  • else
  • Delete(location-gtnext, item)
  • template ltclass ItemTypegt
  • void SortedTypeltItemTypegtDeleteItem(ItemType
  • Delete(listData, item)

Recursion can be very inefficient is some cases
Deciding whether to use a recursive solution
  • When the depth of recursive calls is relatively
  • The recursive version does about the same amount
    of work as the nonrecursive version
  • The recursive version is shorter and simpler than
    the nonrecursive solution
Write a Comment
User Comments (0)