ICS220 Data Structures and Algorithms - PowerPoint PPT Presentation

1 / 27
About This Presentation
Title:

ICS220 Data Structures and Algorithms

Description:

A basic rule for designing new things, is only to include terms which ... data, decodes it and stores it. This has 3 functions; receive(), decode(), store ... – PowerPoint PPT presentation

Number of Views:28
Avg rating:3.0/5.0
Slides: 28
Provided by: ace80
Category:

less

Transcript and Presenter's Notes

Title: ICS220 Data Structures and Algorithms


1
ICS220 Data Structures and Algorithms
  • Dr. Ken Cosh
  • Week 5

2
Review
  • Stacks
  • LIFO
  • Queues
  • FIFO
  • Priority Queues

3
This weeks Topic
  • Recursion
  • Tail Recursion
  • Non-tail Recursion
  • Indirect Recursion
  • Nested Recursion
  • Excessive Recursion

4
Defining new things
  • A basic rule for designing new things, is only to
    include terms which have already been defined.
  • One wouldnt say Mix 3 flugglepips with a
    hippyfrick
  • To define an object in terms of itself is a
    serious violation of this rule a vicious
    circle.
  • However, definitions such as this are called
    recursive definitions.

5
Infinite Sets
  • When defining an infinite set, a complete list of
    the set is impossible, so recursion is often used
    to define them.
  • With large finite sets, it can be more efficient
    to also define them using recursion.

6
Consider defining Natural Numbers
  • 0 ?
  • if n ? then (n1) ?
  • there are no other objects in set
  • According to these rules, the set of natural
    numbers contains
  • 0, 01, 011 etc.

7
Recursion vs Formula
  • When using a recursive definition, it is
    necessary to calculate every value
  • for instance to calculate 6!, first we need to
    know 5!, and then 4! etc.
  • Therefore, sometimes being able to use a formula
    can be less computationally demanding.
  • If n0, g(n) 1
  • if ngt0, g(n) 2g(n-1)
  • This is a recursive function, which can be
    converted to a simple formula What is it?

8
Function Calls
  • What happens when a function is called?
  • If there are formal parameters, they are
    initialised to the values passed.
  • The return address for where the program needs
    to resume after the function completes needs to
    be stored.
  • This return address is key, and for efficiency,
    the memory for the address is allocated
    dynamically using the runtime stack.
  • The runtime stack contains an activation record
    (or frame) for each calling function.

9
Activation Records
  • Activation Records contain
  • Values for all parameters to the function (either
    addresses for call by reference, or copies for
    call by value)
  • Local variables can be stored elsewhere, but the
    activation record will store pointers to their
    locations.
  • The return address, where to resume control in
    the calling function the address of the next
    instruction in the calling function
  • A dynamic link, or pointer, to the callers
    activation record.
  • The returned value for a non-void function.

10
Runtime stack
Parameters and Local Variables
Activation Record for f3()
Dynamic Link
Return Address
Return Value
Parameters and Local Variables
Activation Record for f2()
Dynamic Link
Return Address
Return Value
Parameters and Local Variables
Activation Record for f1()
Dynamic Link
Return Address
Return Value
Activation Record for main()
11
Recursion
  • An activation record is created whenever a
    function is called.
  • This means that each recursive call is not really
    a function calling itself, but instead, an
    instance of a function calling another instance
    of a function.

12
!Factorial!
  • Consider the factorial problem
  • int fact(int n)
  • if (n0)
  • return 1
  • else return n fact(n-1)
  • What happens when this function is called?
  • answer fact(6)

13
Tail Recursion
  • Tail recursion occurs when the final instruction
    in a function is the recursive call (and there
    have been no prior recursive calls).
  • An example is the factorial function on the
    previous slide.

14
Non-Tail Recursion
  • Conversely, in nontail recursion, the recursive
    call is not the final instruction in the
    function. Consider this function.
  • void reverse()
  • char ch
  • cin.get(ch)
  • if (ch ! \n) reverse()
  • cout.put(ch)

15
Indirect Recursion
  • Direct recursion occurs when a function directly
    calls itself indirect recursion is when a
    function calls a function which calls itself or
    similar.
  • f() -gt g() -gt f()
  • Consider a buffer, which receives data, decodes
    it and stores it. This has 3 functions
  • receive(), decode(), store()
  • While there is data to be received, they will
    repeatedly call each other.

16
Nested Recursion
  • Nested recursion occurs when a function is not
    only defined in terms of itself, but is also a
    parameter to the function.
  • If n0, A(n,m) m1
  • If ngt0, m0 A(n,m) A(n-1,1)
  • Else A(n-1, A(n,m-1))
  • N.B. this function (known as the Ackermann
    function) grows very fast
  • A(4,1) is 265536-3,
  • The recursive definition is simple, but as it
    grows faster than addition, multiplication of
    exponentiation, defining it arithmetically is not
    practical.

17
Why Recurse?
  • Logical Simplicity
  • Some mathematical formulas are naturally
    recursive an arithmetic / iterative solution
    may not be simple.
  • Readability
  • Recursive functions are often easier to
    understand and work through.

18
Why not recurse?
  • Excessive use of the runtime stack
  • With the data being stored on the runtime stack,
    there is danger of it running out of space.
  • Speed
  • Some recursive functions can be slow and
    inefficient.

19
Fibonacci
  • Int Fib(int n)
  • if (nlt2)
  • return n
  • else
  • return Fib(n-2) Fib(n-1)
  • How efficient is this recursive function?

20
Fib(5)
  • To calculate Fib(5), first we need Fib(4) and
    Fib(3).
  • To calculate Fib(4), we need Fib(3) and Fib(2).
  • To calculate Fib(3), we need Fib(2) and Fib(1).
  • To calculate Fib(2), we need Fib(1) and Fib(0).
  • To calculate Fib(2), we need Fib(1) and Fib(0).
  • To calculate Fib(3), we need Fib(2) and Fib(1).
  • To calculate Fib(2), we need Fib(1) and Fib(0).

21
Repetition
  • Notice that on the previous slide (which isnt
    complete), we make calls to calculate Fib(2) 3
    times. Each time the call is made the value is
    forgotten by the PC, because of the way unstacked
    data is thrown away.
  • To calculate Fib(6), there are 25 calls to the
    Fib function, and 12 addition operations.

22
Fib(6)
Fib(5)
Fib(4)
Fib(3)
Fib(2)
Fib(4)
Fib(3)
Fib(1)
Fib(0)
Fib(2)
Fib(1)
Fib(2)
Fib(1)
Fib(3)
Fib(2)
Fib(1)
Fib(0)
Fib(1)
Fib(0)
Fib(1)
Fib(0)
Fib(2)
Fib(1)
Fib(1)
Fib(0)
23
Fib Growth
  • The number of additions required for a recursive
    definition is
  • Fib(n 1) - 1
  • For each addition required, there are 2 function
    calls
  • 2Fib(n 1) - 1

24
Fib Growth
25
Recursive Fib
  • The recursive Fib algorithm is simple. But the
    number of calls, and run time grows exponentially
    with n.
  • Recursive Fib is only really practical with small
    n.

26
Alternative Fib
  • int iterativeFib(int n)
  • int previous -1, result1
  • for(int i0 iltn i)
  • int const sumresultprevious
  • previous result
  • result sum
  • return result

27
Iterative Fib
  • The iterative version of fib, is clearly more
    efficient.
  • There is however an even more efficient,
    mathematical approach to approximating Fib(n)
  • int deMoivreFib(int n)
  • return ceil(exp(nlog(1.6180339897)-log(2.2360679
    775))-.5)
Write a Comment
User Comments (0)
About PowerShow.com