230 likes | 364 Vues
Recursive algorithms simplify complex problems by breaking them down into smaller, manageable subproblems of the same type. These algorithms repeatedly apply the same solution process until reaching a base case with a known solution. We explore examples including calculating powers, finding the greatest common divisor (GCD), and executing linear and binary searches. Through detailed procedures, we demonstrate how recursion can effectively solve problems that may be tricky using iterative methods. Discover how recursion works and its practical applications in programming.
E N D
Section 3.5 Recursive Algorithms
Recursive Algorithms • Sometimes we can reduce solution of problem to solution of same problem with set of smaller input values • When such reduction is possible, solution to original problem can be found with series of reductions, until problem is reduced to case for which solution is known • Algorithms which take this approach are called recursive algorithms
Example 1: computing an • Can base algorithm on recursive definition of an: • for n=0, an = 1 • for n>0, an+1 = a(an) • where a is a non-zero real number and n is a non-negative integer procedure power(inputs: a, n) if (n=0) then power(a,n) = 1 else power (a,n) = power(a, n-1)
Extending example 1 • The algorithm in example 1 works only for non-negative powers of non-zero a - we can extend the algorithm to work for all powers of any value a, as follows: procedure power (inputs: a, n) if (a = 0) power(a,n) = 0 else if (n = 0) power(a,n) = 1 else if (n > 0) power(a,n) = (a * power(a, n-1)) else power(a,n) = (1 / rpower(a, -n))
Example 1 int power ( int num, int p) { if (num == 0 ) return 0; if (p ==0) return 1; if (p < 0) return 1 / power(num, -p); return num * power(num, p-1); }
Example 2: computing gcd • The algorithm on the following slide is based on the reduction gcb(a,b) = gcd(b mod a, a) and the condition gcd(0,b) = b where: • a < b • b > 0
Example 2: computing gcd Procedure gcd (inputs: a, b with a < b) if (a=0) then gcd(a,b) = b else gcd(a,b) = gcd(b mod a, a)
Example 2 int gcd (unsigned int smaller, unsigned int larger) { if (larger < smaller) { int tmp = larger; larger = smaller; smaller = tmp; } if (larger == smaller || smaller == 0) return larger; return gcd (larger % smaller, smaller); }
Linear search revisited • The linear, or sequential search algorithm was introduced in section 2.1, as follows: • Examine each item in succession to see if it matches target value • If target found or no elements left to examine, stop search • If target was found, location = found index; otherwise, location = 0
Linear search revisited • In the search for x in the sequence a1 … an, x and ai are compared at the ith step • If x = ai, the search is finished; otherwise the search problem is reduced by one element, since now the sequence to be searched consists of ai+1 … an • Looking at the problem this way, a recursive procedure can be developed
Linear search revisited • Let search(x,y,z) be the procedure that searches for z in the sequence ax … ay • The procedure begins with the triple (x,y,z), terminating when the first term of the sequence is z or when no terms are left to be searched • If z is not the first term and additional terms exist, same procedure is carried out but with input of (x+1, y, z), then with (x+2, y, z), etc.
Linear search revisited Procedure lsearch (x,y,z) if ax = z then location = x else if x = y then location = 0 (not found) else lsearch(x+1, y, z)
Linear search int lsearch(int index, int len, int target, int array[]) { if (index == len) return len; // not found if (array[index]==target) return index; // found return lsearch(index+1, len, target, array); }
Binary search revisited • The binary search algorithm was also introduced in section 2.1: • Works by splitting list in half, then examining the half that might contain the target value • if not found, split and examine again • eventually, set is split down to one element • If the one element is the target, set location to index of item; otherwise, location = 0
Binary search - recursive version procedure bsearch (inputs: x,y,z) mid = (x+y)/2 if z = amid then location = mid (found) else if z < amid and x < mid then bsearch(x, mid-1, z) else if z > amid and y > mid then bsearch (mid+1, y, z) else location = 0 (not found)
Implementation of binary search void BinarySearch(int array[], int first, int size, int target, bool& found, int& location) { size_t middle; if (size == 0) found = false; // base case else { middle = first + size / 2; if (target == array[middle]) { location = middle; found = true; }
Binary search code continued // target not found at current midpoint -- search appropriate half else if (target < array[middle]) BinarySearch (array, first, size/2, target, found, location); // searches from start of array to index before midpoint else BinarySearch (array, middle+1, (size-1)/2, target, found, location); // searches from index after midpoint to end of array } // ends outer else } // ends function
Recursion Vs. Iteration • A recursive definition expresses the value of a function at a positive integer in terms of its value at smaller integers • Another approach is to start with the value of the function at 1 and successively apply the recursive definition to find the value at successively larger integers - this method is called iteration
Example 3: finding n! • Recursive algorithm: int factorial (int n) { if (n==1) return 1; return n * factorial(n-1);} • Iterative algorithm: int factorial (int n) { int x = 1; for (int c = 1; c<= n; c++) x = c * x ; return x; }
Recursion Vs. Iteration • Iterative approach often requires much less computation than recursive procedure • Recursion is best suited to tasks for which there is no obvious iterative solution
Example 4: finding nth term of a sequence • Devise a recursive algorithm to find the nth term of the sequence defined by: • a0 = 1, a1 = 2 • an = an-1 * an-2 for n=2, 3, 4 …
Example 4 int sequence (int n) { if (n < 2) return n+1; return sequence(n-1)*sequence(n-2); }
Section 3.5 Recursive Algorithms - ends -