# Simple Recursion Algorithm by varunpn

VIEWS: 225 PAGES: 23

• pg 1
```									Simple Recursive Algorithms

4-Jan-11
A short list of categories
   Algorithm types we will consider include:
   Simple recursive algorithms
   Backtracking algorithms
   Divide and conquer algorithms
   Dynamic programming algorithms
   Greedy algorithms
   Branch and bound algorithms
   Brute force algorithms
   Randomized algorithms

2
Simple recursive algorithms
   A simple recursive algorithm:
   Solves the base cases directly
   Recurs with a simpler subproblem or subproblems
   May do some extra work to convert the solution to the
simpler subproblem into a solution to the given problem
   I call these “simple” because several of the other
algorithm types are inherently recursive

3
Some example algorithms
   We will look briefly at the following simple
recursive algorithms:
   Factorial
   All permutations
   Tree traversal
   Flood fill
   Quicksort
   Towers of Hanoi
   Ackermann’s function
   We will also consider the equivalence of loops and
recursion

4
Factorial
   The factorial function is the “Hello World” of recursion
   public static long factorial(int n) {
if (n <= 1) return 1;
else return n * factorial(n - 1);
}
   The problem with this example is that it can be done almost
as easily with a loop (so why bother learning recursion?)
   public static long factorial(int n) {
int result = 1;
while (n > 1) {
result *= n;
n--;
}
}
   In the following slides, we look at some example problems
for which recursion really is simpler
5
Permutations
   A permutation of a set of objects is a particular ordering
of those objects
   When we speak of “all permutations” of a set, we mean
all possible ways of ordering those objects
   Examples:
   Given the empty set { }, the only possible permutation is { }
   Given the set {A}, the only possible permutation is {A}
   Given the set {A, B}, the possible permutations are {AB, BA}
   Given the set {A, B, C}, the possible permutations are
{ABC, ACB, BAC, BCA, CAB, CBA}
   Etc.

6
Finding all permutations of n objects
   To find all permutations of n objects:
   Find all permutations of n-1 of those objects
   Insert the remaining object into all possible positions of each
permutation of n-1 objects
   Example: To find all permutations of 3 objects {A, B, C}
   Find all permutations of 2 of the objects, say B and C:
B     C         and           C       B
   Insert the remaining object, A, into all possible positions
(marked by ^) in each of the permutations of B and C:
^ B ^ C ^             and      ^ C ^ B ^
     ABC BAC BCA                    ACB CAB CBA

7
A program to find permutations
   We will develop complete Java code to find all permutations of
a nonempty String of characters
   ArrayList<String> permutationsOf(String s) {
if (s.length() == 1) {
// return a new ArrayList containing just s
}
else {
// separate the first character from the rest
// get all permutationsOf ( the rest of the characters )
// for each permutation,
//      add the first character in all possible positions, and
//      put each result into a new ArrayList
}
// return the new ArrayList
}
8
permutationsOf(String), part I
ArrayList<String> permutationsOf(String s) {
ArrayList<String> result = new ArrayList<String>();

if (s.length() == 1) { // base case
// return a new ArrayList containing just s
return result;
}
// continued...

9
permutationsOf(String), part II
else {
// separate the first character from the rest
char first = s.charAt(0);
String rest = s.substring(1);

// get all permutationsOf the rest of the characters
ArrayList<String> simpler = permutationsOf(rest); // recursive step

// for each permutation,
for (String permutation : simpler) { // extra work
// add the first character in all possible positions, and
// put each result into a new ArrayList
}
return result;
}
}
10
Insert in all positions
   Given one String representing one permutation of n-1 characters,
we want to return all permutations resulting from inserting a
given character in all n possible positions

private ArrayList<String> insertAtAllPositions(char ch, String s) {
ArrayList<String> result = new ArrayList<String>();
for (int i = 0; i <= s.length(); i++) {
String inserted = s.substring(0, i) + ch + s.substring(i);
}
return result;
}

11
Trees
internal
   A tree is composed of nodes            nodes                  root
   Each node contains a value
A
   Each node may have children
   One special node is called the        B       C       D     E
root of the tree
   Nodes with children are           F   G       H       I     J    K
called internal nodes
   Nodes without children are                L       M        N
called leaves
leaves

12
Tree traversals
   It’s easy to traverse (“walk”) a tree recursively
   Here’s a recursive method which, if called with the root of a
tree, will print out all the values in the tree:
   void printTree(Node n) {
print the value in node n;
for each child c of n, printTree(c)
   Or, in actual Java:
void printTree(Node n) {
System.out.println(n.getValue());
Iterator iter = node.getChildren().iterator();
while (iter.hasNext()) {
printTree(iter.next());
}
}
   Many data structures are best handled recursively

13
Flood fill
   To “flood fill” an area with color oldColor, starting
from a particular pixel of color newColor:

   void floodFill(Pixel p, Color oldColor, Color newColor) {
if p is not oldColor, just return
else {
set color of p to newColor
for each pixel q adjacent to p (horizontally or vertically),
floodFill(q, oldColor, newColor)
}
}

14
Quicksort
   Quicksort is (in some sense) the fastest sorting
algorithm known
   From an array of numbers, pick one to use as a pivot
   45 3 17 48 72 25 8 99 14 9 12 21 81 64 33 12
(we’ll use 45 as the pivot)
   Partition the numbers into those smaller than or equal to the
pivot, and those larger than the pivot
   3 17 25 8 14 9 12 21 33 12 45 48 72 99 81 64

Now quicksort the left side:         And the right side:
3 8 9 12 12 14 17 21 25 33 45 48 64 72 81 99

15
Towers of Hanoi
   “Towers of Hanoi” is commonly used as an example
of a problem with a simple recursive solution
   There are three pegs
   The first (source) peg holds some
number of rings
   You want to move all rings to the
last (destination) peg
   You can only move one ring at a
time
   You can never put a larger ring     src   aux   dest
on top of a smaller ring
   You have one auxiliary peg you
can use
16
Solution to Towers of Hanoi

src      aux        dest

   Move the top n-1 rings from src to aux (recursively)
   Move the largest ring from src to dest
   Move the n-1 rings from aux to dest (recursively)

   Notice that there are two recursive calls in this algorithm
   Hence, the number of calls doubles at each level of the recursion
   For a large number of rings, this is a very expensive algorithm!

17
Ackermann’s function
   Ackermann’s function is a deceptively simple little set
of equations:
   A(0, y) = y + 1
   A(x, 0) = A(x - 1, 1)
   A(x, y) = A(x - 1, A(x, y - 1))
   This can easily be written as a recursive method
   A(4, 0) = 13
   A(4, 1) = 65533
   A(4, 2) = 2 65536-3
   After this, the numbers start to get huge quickly
   This function takes a long time to compute (why?)
18
Recursion isn’t necessary
   Computers don’t have “recursive hardware”!
   When a higher-level language is compiled, recursive calls are
implemented with a stack
   When you enter a method, all its local variables (including its formal
parameters) are created and put onto a stack
   The method operates on its own copies of the local variables
   When the method exits, its local variables are removed from the stack
   The compiler changes recursive code into nonrecursive code
   It follows, then, that anything you could do recursively, you
could also do nonrecursively by using loops and a stack

19
Tree traversals, again
   Here’s a recursive method which, if called with the root of a
tree, will print out all the values in the tree:
   void printTree(Node n) {
print the value in node n;
for each child c of n {
printTree(c)
}
}
   Here it is without recursion:
   void printTree(Node n) {
create a new stack s;
push n onto s;
while (s is not empty) {
remove a node m from s and print it
push the children of m (if any) onto stack s
}
}
20
Loops aren’t necessary
   You can replace any recursion with loops (and a stack for local variables)
   In addition, you can replace any loop with a recursion
   For example, consider zeroing out an array:
 static void zeroOut(int[] a) {
for (int i = 0; i < a.length; i++) a[i] = 0;
}
   Or:
 static void zeroOut(int[] a, int n) { // call with n = 0
if (n < a.length) {
a[n] = 0;
zeroOut(a, n + 1);
}
}
   Of course, this is an example, not a proof
   It can be proved (we won’t do it here) that loops can always be replaced by
recursions

21
   The intent of this set of slides is to get you more
familiar with some of the uses of recursion
   Recursion and loops are, in some sense, equivalent--
anything you can do with one, you can do with the
other
   Once you understand recursion, though, it is often
simpler to use recursion than to use loops

22
The End

23

```
To top