Upload
ralf-mosley
View
218
Download
0
Embed Size (px)
Citation preview
Introduction to Data Introduction to Data Structures and Structures and
AlgorithmsAlgorithms
Chapter 6Chapter 6
Recursion (1)Recursion (1)
RecursionRecursionRecursion Definition
• Process:– Expand: A function calls itself with
“smaller parameter”– Converge: A function with parameter x
uses the computation result of function with x-1.
• When terminate the sequence of recursive calls?
– Base case: »A function call with the smallest
parameter needs no further calls; it simply returns result.
Sum of SquaresSum of Squaresint SumSquares(int m, int n) { if (m < n) return m*m + SumSquares (m+1,n); else return m*m;}
Factorials Computation
• N ! = N × (N-1) × (n-2) × … × 1 • Another way to compute factorial?
– Instead of computing factorial, computing multiplication
• Basic Idea (tree structure):– N ! = N × (N -1) ! – (N -1) ! = (N -1) × (N -2) !– …– 1! = 1
int factorial(int n){
int result =1;for (int j=n; j>=1; j--)
result *= j;return result;
}
int factorial(int n){
if (n==1)return 1;
elsereturn ( n * factorial (n-1) );
}
Reversing a ListReversing a List• Partition the list into
– Head --- one node– Tail --- the rest of the list
• Reverse the head and the tail (recursively)
• Combine the two reverse lists
FunctionsFunctions
• getHead• getTail• Node getHead( List mlist), returns
the first node• List getTail (List mlist), returns the
sublist that results after removing the first node
• List Concat (List m1, List m2), joins two sublists
Recursive Reverse List Recursive Reverse List
List reverseL (List mlist) { List head; List tail; if (mlist.first == null) return null; else { head = getHead(mlist); tail = getTail(mlist); return concat (reserseL (tail), head); }}
Binary Search• Binary Search Algorithm (Chapter 2):
– Order array elements– Compare the value of middle element with target – Based on comparison result, change range and middle
element– Keep doing that until a match is found
• Note that each time we apply same logic to different range and middle element
• Can it be done recursively? How?– Develop a function called recFind(key, LowerBond,
Upper Bound)– If key < middle element
• recFind (key, LowerBound, Middle-1)– If key > middle element
• recFind (key, Middle+1, UpperBound)
private int recFind(long searchKey, int lowerBound, int upperBound) { int curIn;
curIn = (lowerBound + upperBound ) / 2; if(a[curIn]==searchKey)
return curIn; // found it else if(lowerBound > upperBound) return nElems; // can't find it else // divide range { if(a[curIn] < searchKey) // it's in upper half return recFind(searchKey, curIn+1, upperBound); else // it's in lower half return recFind(searchKey, lowerBound, curIn-1); } // end else divide range
} // end recFind()
Anagrams
• All possible permutations of the input string• Example: anagrams of cat
– cat; cta; atc; act; tca; tac• Problem: how to compute all anagrams
– Loop idea: many levels of loop– Recursive Idea:
• Anagrams(S) = the first character + anagrams (S-1)
– How many choices for the first character ?– Anagrams (S-1) is different for each possible choice
• Anagramming Recursive Algorithm– Anagram the rightmost n-1 letters– Shift n letters to left by one postion
• cat – atc – tca -- cat– Repeat these steps n times
• Trace anagramming recursive algorithm for the word “cat”– Figure 6.7
public static void doAnagram(int newSize) { int limit; if(newSize == 1) // base case return; // go no further
for(int j=0; j<newSize; j++) // for each position, { doAnagram(newSize-1); // anagram remaining if(newSize==2) // if innermost, displayWord(); // display it rotate(newSize); // rotate word } }
// rotate left all chars from position to end public static void rotate(int newSize) { int j; int position = size - newSize; char temp = arrChar[position]; // save first letter for(j=position+1; j<size; j++) // shift others left arrChar[j-1] = arrChar[j]; arrChar[j-1] = temp; // put first on right }
Tower of Hanoi
• Demo• A number of disks placed on three columns
– S: source column– I: intermediate column– D: destination column
• Rule: – no larger disk is allowed to place on top of
smaller disks
• Idea: – Sub-tree with fewer disks – Sub-trees are formed many times
• Recursive algorithm– Move the sub-tree consisting of the top n-1 disks from S to
I– Move the remaining disk (largest) from S to D– Move the sub-tree from I to D
class TowersApp { static int nDisks = 3;
public static void main(String[] args) { doTowers(nDisks, 'A', 'B', 'C'); } //----------------------------------------------------------- public static void doTowers(int topN, char src, char inter, char dest) { if(topN==1) System.out.println("Disk 1 from " + src + " to "+ dest); else { doTowers(topN-1, src, dest, inter); // src to inter
System.out.println("Disk " + topN + " from " + src + " to "+ dest); doTowers(topN-1, inter, src, dest); // inter to dest } }//------------------------------------------------------------- } // end class TowersApp
Trace Algorithm: Page 279
• Running time analysis:– Depends on number of recursive calls
• Examples:– Factorial O(?)– Binary search O(?)– Anagram O(?)
Divide-and-Conquer approach
• divide a big problem into two smaller problems and solve them separately. The process continues until you get to the base case, which can be solved easily
• Divide-and-conquer approach usually involves two recursive calls, one for each smaller problems
• Lots of time, you will see O(n2) algorithm can be improved to O(nlogn) with Divide-and-conquer approach
• Exercise 1: String length computation– Compute the length of an input string recursively
• Exercise 2: Teddy Bear Game– Initially, you have initial number of bears– Each step, you can do one of the followings:
• Ask for increment number of bears• Give away half of bears if you have even number of
bears– Goal: reach goalgoal number of bears within nn steps
– How do you know if you can reach goal or not?