Non Re Cursive
Non Re Cursive
Non Re Cursive
MaxElement
Finding the value of the largest element in the list of n numbers
MaxElement(A[1..n]) maxval A[1] for i 2 to n do if A[i] > maxval maxval A[i] return maxval
Complexity of Algorithm
The Loop is repeated n-1 times so
UniqueElement
UniqueElement(A[1..n]) for i 1 to n-1 do for j i+1 to n do{ if A[i] = A[j] return false} return true
complexity
Binary digits in the binary representation of a positive decimal integer Algorithm Binary(n) { count 1 while n>1 { Count count+1 n [n/2] } return count}
Fibonacci series
Algorithm Fibonacci(n) { if n<1 Return n; Else F1 0, F2 1; For i 2 to n do { F F1+F2 F1 F2 F2 F }return F
What is recursion?recursion When one function calls ITSELF directly or indirectly. Recursion means defining something, such as a function, in terms of itself
For example, let f(x) = x! We can define f(x) as f(x) = x * f(x-1)
Mathematics
Definition of the set of non negative numbers N
0 is in N If n is in N, then n+1 is in N.
Images
Fractals
Fractals
A fractal is a pattern that uses recursion
The pattern itself repeats indefinitely
13
Fractals
14
The value of an onion is the number of layers of skin beyond the core s(0) = 1 s(s(0)) = 2 s(s(s(0))) = 3
Meaning of recursion
To recur means to happen again. In computer science, we say that a subroutine (function or procedure) is recursive when it calls itself one or more times. We call the programming technique by using recursive subroutine(s) as recursion.
Recursive Function
a kind of function that calls itself, or a function that is part of a cycle in the sequence of function calls.
f1
f1
f2
fn
One or more simple cases of the problem have a straightforward solution. The other cases can be redefined in terms of problems that are closer to the simple cases. The problem can be reduced entirely to simple cases by calling the recursive function.
If this is a simple case solve it else redefine the problem using recursion
Assume that the problem of size 1 can be solved easily (i.e., the simple case). We can recursively split the problem into a problem of size 1 and another problem of size n1.
b)
n! _ ( n 1)! =n
n
Permutation
Pr _ nn 1 Pr =
Combination
n
Cr _ ( n / r )n 1 Cr =
Pascal relationship
n
Cr = n 1 Cr 1 + n 1 Cr _
Integer power
x n = x x n 1 _
Structure of recursion
Similar to mathematic induction, recursion requires the following two components
Recurrence relation(s) Base case(s)
Example F(n) IF (n=0) RETURN 1 ELSE RETURN n*F(n-1) //Base Case //Recurrence Relation
Recurrence Relations
1. Base Case: the initial condition or basis which defines the first (or first few) elements of the sequence Inductive (Recursive) Case: an inductive step in which later terms in the sequence are defined in terms of earlier terms. 2.
A recurrence relation for a sequence a1, a2, a3, ... is a formula that relates each term a k to certain of its predecessors ak-1, ak-2, ..., a k-i, where i is a fixed integer and k is any integer greater than or equal to i. The initial conditions for such a recurrence relation specify the values of a1, a2, a3, ..., ai-1.
Recursive Definition
We can also define the factorial function in the following way:
Recursive Algorithm
factorial(n) { if (n = 0) return 1 else return n*factorial(n-1) end if }
Recursion
To see how the recursion works, lets break down the factorial function to solve factorial(3)
Breakdown
Here, we see that we start at the top level, factorial(3), and simplify the problem into 3 x factorial(2). Now, we have a slightly less complicated problem in factorial(2), and we simplify this problem into 2 x factorial(1).s
Breakdown
We continue this process until we are able to reach a problem that has a known solution. In this case, that known solution is factorial(0) = 1. The functions then return in reverse order to complete the solution.
The basic operation of the algorithm is multiplication, whose number of executions we denote M(n). Since the function F(n) is computed according to the formula F(n)=F(n-1).n for n>0
Complexity O(n)
Fibonacci Numbers
The Fibonacci numbers, a famous sequence 0,1,1,2,3,5,8,13,21,34.. That can be defined by the simple recurrence
fibonacci
int Fibonacci (int n) { if ( (n == 1) || (n == 2) ) return 1; else return Fibonacci (n-1) + Fibonacci (n-2); }
36
y > 0
Infinite recursion
a definition with a missing or badly written base case causes infinite recursion, similar to an infinite loop
avoided by making sure that the recursive call gets closer to the solution (moving toward the base case)
int pow(int x, int y) { return x * pow(x, y - 1); case } pow(4, 3) = = = = = = 4 * 4 * 4 * 4 * 4 * ... // Oops! Forgot base
pow(4, 2) 4 * pow(4, 1) 4 * 4 * pow(4, 0) 4 * 4 * 4 * pow(4, -1) 4 * 4 * 4 * 4 * pow(4, -2) crashes: Stack Overflow Error!
39
How C Maintains the Recursive Steps of variables by the C keeps track of the values
stack data structure.
Recall that stack is a data structure where the last item added is the first item processed. There are two operations (push and pop) associated with stack.
a b c pop b c push d d b c
Activation records
activation record: memory allocates to store information about each running method
return point ("RP"), argument values, local variable values stacks up the records as methods are called; a method's activation record exists until it returns drawing the act. records helps us trace the behavior of a recursive method
[ 4 ] [pow(4,1)] [ 4 ] [pow(4,2)] [ 4 ] [pow(4,3)] [ 4 ] [main] _ y = [ 0 ] | | y = [ 1 ] | | y = [ 2 ] | | y = [ 3 ] | | | pow(4, 0) pow(4, 1) pow(4, 2) pow(4, 3) main
| | | | | | | | |
x RP x RP x RP x RP
= = = = = = = =
42
if n=0 if n>0
if n=0 if n>0
Recursion
Uses more storage than iteration Runs slower due to runtime overhead
however, for some problems recursive solutions are often more simple and elegant than iterative solutions you must be able to determine when recursion is appropriate
44
From a practical software engineering point of view these are important benefits, greatly enhancing the cost of maintaining the software.
Limitations of Recursion
In general, recursive algorithms run slower than their iterative counterparts. Also, every time we make a call, we must use some of the memory resources to make room for the stackframe.
Limitations of Recursion
Recursive solutions may involve extensive overhead because they use calls. When a call is made, it takes time to build a stackframe and push it onto the system stack. Conversely, when a return is executed, the stackframe must be popped from the stack and the local variables reset to their previous values this also takes time.
Limitations of Recursion
Consider the recursive Fibonacci generator How many recursive calls does it make?
F(1): 1 F(2): 1 F(3): 3 F(4): 5 F(5): 9 F(10): 109 F(20): 13,529 F(30): 1,664,079 F(40): 204,668,309 F(50): 25,172,538,049 F(100): 708,449,696,358,523,830,149 7 * 1020
At 1 billion recursive calls per second (generous), this would take over 22,000 years But that would also take well over 1012 Gb of memory!
Limitations of Recursion
Therefore, if the recursion is deep, say, factorial(1000), we may run out of memory. Because of this, it is usually best to develop iterative algorithms when we are working with large numbers.
Algorithm Visualization
Static Algorithm Visualization (series of still images) Dynamic Algorithm Visualization (Animation)