220 likes | 309 Views
Chapter 15. Recursive Algorithms. Recursion. Recursion is a programming technique in which a method can call itself to solve a problem
E N D
Chapter 15 Recursive Algorithms
Recursion • Recursion is a programming technique in which a method can call itself to solve a problem • A recursive definition is one which uses the word or concept being defined in the definition itself; when defining an English word, a recursive definition usually is not helpful
Basic Elements of Recursion • A recursive method is a method that contains a statement that makes a call to itself. • Any recursive method will include the following three basic elements: • A test to stop or continue the recursion. • An end case that terminates the recursion. • A recursive call that continues the recursion.
Recursive Definitions • Mathematical formulas often are expressed recursively • N!, for any positive integer N, is defined to be the product of all integers between 1 and N inclusive • This definition can be expressed recursively as: 1! = 1 N! = N * (N-1)! • The concept of the factorial is defined in terms of another factorial until the base case of 1! is reached
Recursive Definitions 120 24 6 2 5! 5 * 4! 4 * 3! 3 * 2! 2 * 1! 1
Infinite Recursion • All recursive definitions must have a non-recursive part • If they don't, there is no way to terminate the recursive path • A definition without a non-recursive part causes infinite recursion • This problem is similar to an infinite loop with the definition itself causing the infinite "loop" • The non-recursive part often is called the base case
Recursive Factorial Method • Factorial: n! = n*(n-1)*(n-2)* … * 2 * 1 public int factorial(int N) { if (N == 1){ return 1; } else { return N * factorial(N-1); } }
Recursive Directory Listing • Recursive algorithms may be used for nonnumerical applications. • This example of a recursive algorithm will list the file names of all files in a given directory of a hard disk and its subdirectories.
Directory Listing • We create a new File object by passing the name of a file or a directory: • File file = new File(“D:/Java/Projects”); • To get an array of names of files and subdirectories, we use the list method. • String[] fileList = file.list();
Anagram • We can use a recursive method to derive all anagrams of a given word. • When we find the end case (an anagram), we will print it out.
Anagram Algorithm • How to generate all the anagrams of a word by using recursion.
Finding Anagrams • We find the anagrams by rotating the positions of the letters. • The trick is, when the method is called recursively, we pass a word with the first letter cut off. So the words being passed to successive calls are getting shorter and shorter. • However, we must access all letters of the word in order to print it out.
Anagrams • We solve this problem by passing two parameters: the prefix and the suffix of a word. • In each successive call, the prefix increases by one letter and the suffix decreases by one letter. • When the suffix becomes one letter only, the recursion stops.
Towers of Hanoi • The goal of the Towers of Hanoi puzzle is to move N disks from peg 1 to peg 3: • You must move one disk at a time. • You must never place a larger disk on top of a smaller disk.
Towers of Hanoi • This puzzle can be solved effectively using recursion. • The top N-1 disks must be moved to peg 2, allowing you to then move the largest disk from peg 1 to peg 3. • You can then move the N-1 disks from peg 2 to peg 3.
Recursive Sorting Algorithms • There are two commonly used sorting methods that use recursion • Merge sort: sort each half of the array and merge the sorted halves together • Quicksort: use a pivot value to separate the array into two parts • Both these methods are more efficient that the sorts we’ve seen before • N log N instead of N2
When Not to Use Recursion • Recursion does not always provide an efficient or natural way to express the solution to a problem. public int fibonacci(int N){ if (N == 0 )|| N ==1){ return 1; //end case }else{ //recursive case return fibonacci(N-1) + fibonacci(N-2); } }
Fibonacci • Recursive calls to compute fibonacci(5).
Recursive Fibonacci • This method is succinct and easy to understand, but it is very inefficient. A nonrecursive version is just as easy to understand.
Non-Recursive Fibonacci public int fibonacci(int N){ int fibN, fibN1, fibN2, cnt; if (N == 0 || N == 1){ return 1; }else{ fibN1 = fibN2 = 1; cnt = 2; while (cnt <= N){ fibN = fibN1 + fibN2; //get next Fib. no. fibN1 = fibN2; fibN2 = fibN; cnt++; } return fibN; }}
When to Use Recursion • In general, use recursion if • A recursive solution is natural and easy to understand. • A recursive solution does not result in excessive duplicate computation. • The equivalent iterative solution is too complex.