KEMBAR78
Recursion.pdf
Recursion
Introduction to Recursion
• So far, we have seen methods that call other
functions.
– For example, the main() method calls the square()
function.
• Recursive Method:
– A recursive method is a method that calls itself.
main()
square()
compute()
!3
Recursion
In some problems, it may be natural to define
the problem in terms of the problem itself.
Recursion is useful for problems that can be
represented by a simpler version of the same
problem.
Example: the factorial function
6! = 6 * 5 * 4 * 3 * 2 * 1
We could write:
6! = 6 * 5!
!4
Example 2: factorial function
In general, we can express the factorial
function as follows:
n! = n * (n-1)!
Is this correct? Well… almost.
The factorial function is only defined for
positive integers. So we should be a bit more
precise:
n! = 1 (if n is equal to 1)
n! = n * (n-1)! (if n is larger than 1)
Recursive Definitions (cont’d.)
• Direct solution (EQ1)
– Right side of the equation contains no factorial
notation
• Recursive definition
– A definition in which something is defined in terms of a
smaller version of itself
• Base case (EQ1)
– Case for which the solution is obtained directly
• General case (EQ2)
– Case for which the solution is obtained indirectly using
recursion
Data Structures Using C++ 2E !5
!6
factorial function
The C++ equivalent of this definition:
int fac(int numb){
if(numb<=1)
return 1;
else
return numb * fac(numb-1);
}
recursion means that a function calls itself
!7
factorial function
Assume the number typed is 3, that is, numb=3.
fac(3) :
int fac(int numb){
if(numb<=1)
return 1;
else
return numb * fac(numb-1);
}
3 <= 1 ? No.
fac(3) = 3 * fac(2)
fac(2) :
2 <= 1 ? No.
fac(2) = 2 * fac(1)
fac(1) :
1 <= 1 ? Yes.
return 1
fac(2) = 2 * 1 = 2
return fac(2)
fac(3) = 3 * 2 = 6
return fac(3)
fac(3) has the value 6
!8
Recursive Definitions (cont’d.)
• Recursive function implementing the factorial
function
FIGURE 6-1 Execution of fact(3)
!9
factorial function
For certain problems (such as the factorial function), a
recursive solution often leads to short and elegant code.
Compare the recursive solution with the iterative solution:
Iterative solution
int fac(int numb){
int product=1;
while(numb>1){
product *= numb;
numb--;
}
return product;
}
Recursive solution
int fac(int numb){
if(numb<=1)
return 1;
else
return numb*fac(numb-1);
}
© 2003 Prentice Hall, Inc. All rights reserved.
!10
Recursion vs. Iteration
• Iteration
– Uses repetition structures (for, while or do…while)
– Repetition through explicitly use of repetition structure
– Terminates when loop-continuation condition fails
– Controls repetition by using a counter
• Recursion
– Uses selection structures (if, if…else or switch)
– Repetition through repeated method calls
– Terminates when base case is satisfied
– Controls repetition by dividing problem into simpler one
© 2003 Prentice Hall, Inc. All rights reserved.
!11
Recursion vs. Iteration (cont.)
• Recursion
– More overhead than iteration
– More memory intensive than iteration
– Can also be solved iteratively
– Often can be implemented with only a few lines of code
!12
Recursion
We have to pay a price for recursion:
calling a function consumes more time and memory than
adjusting a loop counter.
high performance applications (graphic action games,
simulations of nuclear explosions) hardly ever use recursion.
In less demanding applications recursion is an
attractive alternative for iteration (for the right
problems!)
Recursive Definitions (cont’d.)
• Recursive function notable comments
– Recursive function has unlimited number of copies of
itself (logically)
– Every call to a recursive function has its own
• Code, set of parameters, local variables
– After completing a particular recursive call
• Control goes back to calling environment (previous call)
• Current (recursive) call must execute completely before
control goes back to the previous call
• Execution in previous call begins from point immediately
following the recursive call
!13
!14
Recursive Definitions (cont’d.)
• Direct and indirect recursion
– Directly recursive function
• Calls itself
– Indirectly recursive function
• Calls another function, eventually results in original
function call
• Requires same analysis as direct recursion
• Base cases must be identified, appropriate solutions to
them provided
• Tracing can be tedious
Data Structures Using C++ 2E !15
Recursive Definitions (cont’d.)
• Infinite recursion
– Occurs if every recursive call results in another
recursive call
– Executes forever (in theory)
– Call requirements for recursive functions
• System memory for local variables and formal
parameters
• Saving information for transfer back to right caller
– Finite system memory leads to
• Execution until system runs out of memory
• Abnormal termination of infinite recursive function
Data Structures Using C++ 2E !16
Recursive Definitions (cont’d.)
• Requirements to design a recursive function
– Understand problem requirements
– Determine limiting conditions
– Identify base cases, providing direct solution to each
base case
– Identify general cases, providing solution to each
general case in terms of smaller versions of itself
!17
Recursion
If we use iteration, we must be careful not to create
an infinite loop by accident:
for(int incr=1; incr!=10;incr+=2)
...
int result = 1;
while(result >0){
...
result++;
}
Oops!
Oops!
!18
Recursion
Similarly, if we use recursion we must be
careful not to create an infinite chain of
function calls:
int fac(int numb){
return numb * fac(numb-1);
}
Or:
int fac(int numb){
if (numb<=1)
return 1;
else
return numb * fac(numb+1);
}
Oops!
No termination
condition
Oops!
!19
Recursion
We must always make sure that the recursion
bottoms out:
A recursive function must contain at least one
non-recursive branch.
The recursive calls must eventually lead to a
non-recursive branch.
!20
Recursion
Recursion is one way to decompose a task into
smaller subtasks. At least one of the subtasks is
a smaller example of the same task.
The smallest example of the same task has a
non-recursive solution.
Example: The factorial function
n! = n * (n-1)! and 1! = 1
!21
How many pairs of rabbits can be produced from a
single pair in a year's time?
Assumptions:
Each pair of rabbits produces a new pair of offspring every month;
each new pair becomes fertile at the age of one month;
none of the rabbits dies in that year.
Example:
After 1 month there will be 2 pairs of rabbits;
after 2 months, there will be 3 pairs;
after 3 months, there will be 5 pairs (since the following month the original
pair and the pair born during the first month will both produce a new pair
and there will be 5 in all).
!22
Population Growth in Nature
Leonardo Pisano (Leonardo Fibonacci = Leonardo, son of
Bonaccio) proposed the sequence in 1202 in The Book of the
Abacus.
Fibonacci numbers are believed to model nature to a certain
extent, such as Kepler's observation of leaves and flowers in
1611.
!23
Direct Computation Method
Fibonacci numbers:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
where each number is the sum of the preceding
two.
Recursive definition:
F(0) = 0;
F(1) = 1;
F(number) = F(number-1)+ F(number-2);
!24
!25
Example 3: Fibonacci numbers
//Calculate Fibonacci numbers using recursive function.
//A very inefficient way, but illustrates recursion well
int fib(int number)
{
if (number == 0) return 0;
if (number == 1) return 1;
return (fib(number-1) + fib(number-2));
}
int main(){ // driver function
int inp_number;
cout << "Please enter an integer: ";
cin >> inp_number;
cout << "The Fibonacci number for "<< inp_number
<< " is "<< fib(inp_number)<<endl;
return 0;
}
!26
Copyright © 2000 by Brooks/Cole Publishing Company
!27
Trace a Fibonacci Number
Assume the input number is 4, that is, num=4:
fib(4):
4 == 0 ? No; 4 == 1? No.
fib(4) = fib(3) + fib(2)
fib(3):
3 == 0 ? No; 3 == 1? No.
fib(3) = fib(2) + fib(1)
fib(2):
2 == 0? No; 2==1? No.
fib(2) = fib(1)+fib(0)
fib(1):
1== 0 ? No; 1 == 1? Yes.
fib(1) = 1;
return fib(1);
int fib(int num)
{
if (num == 0) return 0;
if (num == 1) return 1;
return
(fib(num-1)+fib(num-2));
}
!28
Trace a Fibonacci Number
fib(0):
0 == 0 ? Yes.
fib(0) = 0;
return fib(0);
fib(2) = 1 + 0 = 1;
return fib(2);
fib(3) = 1 + fib(1)
fib(1):
1 == 0 ? No; 1 == 1? Yes
fib(1) = 1;
return fib(1);
fib(3) = 1 + 1 = 2;
return fib(3)
!29
Trace a Fibonacci Number
fib(2):
2 == 0 ? No; 2 == 1? No.
fib(2) = fib(1) + fib(0)
fib(1):
1== 0 ? No; 1 == 1? Yes.
fib(1) = 1;
return fib(1);
fib(0):
0 == 0 ? Yes.
fib(0) = 0;
return fib(0);
fib(2) = 1 + 0 = 1;
return fib(2);
fib(4) = fib(3) + fib(2)
= 2 + 1 = 3;
return fib(4);
!30
Example 4: Fibonacci number w/o
recursion
//Calculate Fibonacci numbers iteratively
//much more efficient than recursive solution
int fib(int n)
{
int f[100];
f[0] = 0; f[1] = 1;
for (int i=2; i<= n; i++)
f[i] = f[i-1] + f[i-2];
return f[n];
}
!31
Fibonacci Numbers
Fibonacci numbers can also be represented by the
following formula.
!32
Example 5: Binary Search
Search for an element in an array
!Sequential search
!Binary search
Binary search
!Compare the search element with the
middle element of the array
!If not equal, then apply binary search to
half of the array (if not empty) where the
search element would be.
see applet
!33
Binary Search with Recursion
// Searches an ordered array of integers using recursion
int bsearchr(const int data[], // input: array
int first, // input: lower bound
int last, // input: upper bound
int value // input: value to find
)// output: index if found, otherwise return –1
{ //cout << "bsearch(data, "<<first<< ", last "<< ", "<<value << "); "<<endl;
int middle = (first + last) / 2;
if (data[middle] == value)
return middle;
else if (first >= last)
return -1;
else if (value < data[middle])
return bsearchr(data, first, middle-1, value);
else
return bsearchr(data, middle+1, last, value);
}
!34
Binary Search
int main() {
const int array_size = 8;
int list[array_size]={1, 2, 3, 5, 7, 10, 14, 17};
int search_value;
cout << "Enter search value: ";
cin >> search_value;
cout << bsearchr(list,0,array_size-1,search_value)
<< endl;
return 0;
}
!35
Binary Search w/o recursion
// Searches an ordered array of integers
int bsearch(const int data[], // input: array
int size, // input: array size
int value // input: value to find
){ // output: if found,return
// index; otherwise, return -1
int first, last, upper;
first = 0;
last = size - 1;
while (true) {
middle = (first + last) / 2;
if (data[middle] == value)
return middle;
else if (first >= last)
return -1;
else if (value < data[middle])
last = middle - 1;
else
first = middle + 1;
}
}
!36
Recursion General Form
How to write recursively?
int recur_fn(parameters){
if(stopping condition)
return stopping value;
// other stopping conditions if needed
return function of recur_fn(revised parameters)
}
!37
Example 6: exponential func
How to write exp(int numb, int power)
recursively?
int exp(int numb, int power){
if(power ==0)
return 1;
return numb * exp(numb, power -1);
}
!38
Example 6: number of zero
Write a recursive function that counts the number of zero
digits in an integer
zeros(10200) returns 3.
int zeros(int numb){
if(numb==0) // 1 digit (zero/non-zero):
return 1; // bottom out.
else if(numb < 10 && numb > -10)
return 0;
else // > 1 digits: recursion
return zeros(numb/10) + zeros(numb%10);
}
zeros(10200)
zeros(1020) + zeros(0)
zeros(102) + zeros(0) + zeros(0)
zeros(10) + zeros(2) + zeros(0) + zeros(0)
zeros(1) + zeros(0) + zeros(2) + zeros(0) + zeros(0)
!39
Problem Solving Using Recursion
Let us consider a simple problem of printing a message for n times.
You can break the problem into two subproblems: one is to print the
message one time and the other is to print the message for n-1 times.
The second problem is the same as the original problem with a
smaller size. The base case for the problem is n==0. You can solve
this problem using recursion as follows:
void nPrintln(char * message, int times)
{
if (times >= 1) {
cout << message << endl;
nPrintln(message, times - 1);
} // The base case is n == 0
}
!40
Think Recursively
Many of the problems can be solved easily using recursion if you
think recursively. For example, the palindrome problem can be
solved recursively as follows:
bool isPalindrome(const char * const s)
{
if (strlen(s) <= 1) // Base case
return true;
else if (s[0] != s[strlen(s) - 1]) // Base case
return false;
else
return isPalindrome(substring(s, 1, strlen(s) - 2));
}
!41
Recursive Helper Methods
The preceding recursive isPalindrome method is not efficient, because it creates a
new string for every recursive call. To avoid creating new strings, use a helper
method:
bool isPalindrome(const char * const s, int low, int high)
{
if (high <= low) // Base case
return true;
else if (s[low] != s[high]) // Base case
return false;
else
return isPalindrome(s, low + 1, high - 1);
}
bool isPalindrome(const char * const s)
{
return isPalindrome(s, 0, strlen(s) - 1);
}
!42
Example 7: Towers of Hanoi
Only one disc could be moved at a time
A larger disc must never be stacked above
a smaller one
One and only one extra needle could be
used for intermediate storage of discs
see applet
!43
Towers of Hanoi
void hanoi(int from, int to, int num)
{
int temp = 6 - from - to; //find the temporary
//storage column
if (num == 1){
cout << "move disc 1 from " << from
<< " to " << to << endl;
}
else {
hanoi(from, temp, num - 1);
cout << "move disc " << num << " from " << from
<< " to " << to << endl;
hanoi(temp, to, num - 1);
}
}
!44
Towers of Hanoi
int main() {
int num_disc; //number of discs
cout << "Please enter a positive number (0 to quit)";
cin >> num_disc;
while (num_disc > 0){
hanoi(1, 3, num_disc);
cout << "Please enter a positive number ";
cin >> num_disc;
}
return 0;
}
!45
Eight Queens
0
4
7
5
2
6
1
3
queens[0]
queens[1]
queens[2]
queens[3]
queens[4]
queens[5]
queens[6]
queens[7]
Place eight queens on the chessboard such that no queen attacks
any other one.
!46
bool empty(int t[], int row, int col) {
for( int j = 0; j < row; j++) {
if (t[j] == col) //same column
return false;
if (abs(t[j] - col) == (row - j)) //on cross line
return false;
}
return true;
}
bool queens(int t[], int row, int col) {
if (row == SIZE) // found one answer
return true;
for (col = 0; col <SIZE; col++)
{
t[row] = col;
if (empty(t, row, col) && queens(t, row +1, 0))
return true;
}
return false;
}
void print(int t[]){
// print solution
for(int i = 0; i < SIZE; i++) {
for(int j = 0; j < SIZE; j++) {
if (j == t[i])
cout << " Q ";
else
cout << " _ ";
}
cout << endl;
}
}
int main() {
int t[SIZE]={0};
for (int i= 0; i <SIZE; i++){
t[0] = i; //on first row, Queen on different column
cout << endl << endl <<"i is: " << i << endl;
if (queens(t, 1,0))
print(t);
}
}

Recursion.pdf

  • 1.
  • 2.
    Introduction to Recursion •So far, we have seen methods that call other functions. – For example, the main() method calls the square() function. • Recursive Method: – A recursive method is a method that calls itself. main() square() compute()
  • 3.
    !3 Recursion In some problems,it may be natural to define the problem in terms of the problem itself. Recursion is useful for problems that can be represented by a simpler version of the same problem. Example: the factorial function 6! = 6 * 5 * 4 * 3 * 2 * 1 We could write: 6! = 6 * 5!
  • 4.
    !4 Example 2: factorialfunction In general, we can express the factorial function as follows: n! = n * (n-1)! Is this correct? Well… almost. The factorial function is only defined for positive integers. So we should be a bit more precise: n! = 1 (if n is equal to 1) n! = n * (n-1)! (if n is larger than 1)
  • 5.
    Recursive Definitions (cont’d.) •Direct solution (EQ1) – Right side of the equation contains no factorial notation • Recursive definition – A definition in which something is defined in terms of a smaller version of itself • Base case (EQ1) – Case for which the solution is obtained directly • General case (EQ2) – Case for which the solution is obtained indirectly using recursion Data Structures Using C++ 2E !5
  • 6.
    !6 factorial function The C++equivalent of this definition: int fac(int numb){ if(numb<=1) return 1; else return numb * fac(numb-1); } recursion means that a function calls itself
  • 7.
    !7 factorial function Assume thenumber typed is 3, that is, numb=3. fac(3) : int fac(int numb){ if(numb<=1) return 1; else return numb * fac(numb-1); } 3 <= 1 ? No. fac(3) = 3 * fac(2) fac(2) : 2 <= 1 ? No. fac(2) = 2 * fac(1) fac(1) : 1 <= 1 ? Yes. return 1 fac(2) = 2 * 1 = 2 return fac(2) fac(3) = 3 * 2 = 6 return fac(3) fac(3) has the value 6
  • 8.
    !8 Recursive Definitions (cont’d.) •Recursive function implementing the factorial function FIGURE 6-1 Execution of fact(3)
  • 9.
    !9 factorial function For certainproblems (such as the factorial function), a recursive solution often leads to short and elegant code. Compare the recursive solution with the iterative solution: Iterative solution int fac(int numb){ int product=1; while(numb>1){ product *= numb; numb--; } return product; } Recursive solution int fac(int numb){ if(numb<=1) return 1; else return numb*fac(numb-1); }
  • 10.
    © 2003 PrenticeHall, Inc. All rights reserved. !10 Recursion vs. Iteration • Iteration – Uses repetition structures (for, while or do…while) – Repetition through explicitly use of repetition structure – Terminates when loop-continuation condition fails – Controls repetition by using a counter • Recursion – Uses selection structures (if, if…else or switch) – Repetition through repeated method calls – Terminates when base case is satisfied – Controls repetition by dividing problem into simpler one
  • 11.
    © 2003 PrenticeHall, Inc. All rights reserved. !11 Recursion vs. Iteration (cont.) • Recursion – More overhead than iteration – More memory intensive than iteration – Can also be solved iteratively – Often can be implemented with only a few lines of code
  • 12.
    !12 Recursion We have topay a price for recursion: calling a function consumes more time and memory than adjusting a loop counter. high performance applications (graphic action games, simulations of nuclear explosions) hardly ever use recursion. In less demanding applications recursion is an attractive alternative for iteration (for the right problems!)
  • 13.
    Recursive Definitions (cont’d.) •Recursive function notable comments – Recursive function has unlimited number of copies of itself (logically) – Every call to a recursive function has its own • Code, set of parameters, local variables – After completing a particular recursive call • Control goes back to calling environment (previous call) • Current (recursive) call must execute completely before control goes back to the previous call • Execution in previous call begins from point immediately following the recursive call !13
  • 14.
    !14 Recursive Definitions (cont’d.) •Direct and indirect recursion – Directly recursive function • Calls itself – Indirectly recursive function • Calls another function, eventually results in original function call • Requires same analysis as direct recursion • Base cases must be identified, appropriate solutions to them provided • Tracing can be tedious
  • 15.
    Data Structures UsingC++ 2E !15 Recursive Definitions (cont’d.) • Infinite recursion – Occurs if every recursive call results in another recursive call – Executes forever (in theory) – Call requirements for recursive functions • System memory for local variables and formal parameters • Saving information for transfer back to right caller – Finite system memory leads to • Execution until system runs out of memory • Abnormal termination of infinite recursive function
  • 16.
    Data Structures UsingC++ 2E !16 Recursive Definitions (cont’d.) • Requirements to design a recursive function – Understand problem requirements – Determine limiting conditions – Identify base cases, providing direct solution to each base case – Identify general cases, providing solution to each general case in terms of smaller versions of itself
  • 17.
    !17 Recursion If we useiteration, we must be careful not to create an infinite loop by accident: for(int incr=1; incr!=10;incr+=2) ... int result = 1; while(result >0){ ... result++; } Oops! Oops!
  • 18.
    !18 Recursion Similarly, if weuse recursion we must be careful not to create an infinite chain of function calls: int fac(int numb){ return numb * fac(numb-1); } Or: int fac(int numb){ if (numb<=1) return 1; else return numb * fac(numb+1); } Oops! No termination condition Oops!
  • 19.
    !19 Recursion We must alwaysmake sure that the recursion bottoms out: A recursive function must contain at least one non-recursive branch. The recursive calls must eventually lead to a non-recursive branch.
  • 20.
    !20 Recursion Recursion is oneway to decompose a task into smaller subtasks. At least one of the subtasks is a smaller example of the same task. The smallest example of the same task has a non-recursive solution. Example: The factorial function n! = n * (n-1)! and 1! = 1
  • 21.
    !21 How many pairsof rabbits can be produced from a single pair in a year's time? Assumptions: Each pair of rabbits produces a new pair of offspring every month; each new pair becomes fertile at the age of one month; none of the rabbits dies in that year. Example: After 1 month there will be 2 pairs of rabbits; after 2 months, there will be 3 pairs; after 3 months, there will be 5 pairs (since the following month the original pair and the pair born during the first month will both produce a new pair and there will be 5 in all).
  • 22.
    !22 Population Growth inNature Leonardo Pisano (Leonardo Fibonacci = Leonardo, son of Bonaccio) proposed the sequence in 1202 in The Book of the Abacus. Fibonacci numbers are believed to model nature to a certain extent, such as Kepler's observation of leaves and flowers in 1611.
  • 23.
    !23 Direct Computation Method Fibonaccinumbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... where each number is the sum of the preceding two. Recursive definition: F(0) = 0; F(1) = 1; F(number) = F(number-1)+ F(number-2);
  • 24.
  • 25.
    !25 Example 3: Fibonaccinumbers //Calculate Fibonacci numbers using recursive function. //A very inefficient way, but illustrates recursion well int fib(int number) { if (number == 0) return 0; if (number == 1) return 1; return (fib(number-1) + fib(number-2)); } int main(){ // driver function int inp_number; cout << "Please enter an integer: "; cin >> inp_number; cout << "The Fibonacci number for "<< inp_number << " is "<< fib(inp_number)<<endl; return 0; }
  • 26.
    !26 Copyright © 2000by Brooks/Cole Publishing Company
  • 27.
    !27 Trace a FibonacciNumber Assume the input number is 4, that is, num=4: fib(4): 4 == 0 ? No; 4 == 1? No. fib(4) = fib(3) + fib(2) fib(3): 3 == 0 ? No; 3 == 1? No. fib(3) = fib(2) + fib(1) fib(2): 2 == 0? No; 2==1? No. fib(2) = fib(1)+fib(0) fib(1): 1== 0 ? No; 1 == 1? Yes. fib(1) = 1; return fib(1); int fib(int num) { if (num == 0) return 0; if (num == 1) return 1; return (fib(num-1)+fib(num-2)); }
  • 28.
    !28 Trace a FibonacciNumber fib(0): 0 == 0 ? Yes. fib(0) = 0; return fib(0); fib(2) = 1 + 0 = 1; return fib(2); fib(3) = 1 + fib(1) fib(1): 1 == 0 ? No; 1 == 1? Yes fib(1) = 1; return fib(1); fib(3) = 1 + 1 = 2; return fib(3)
  • 29.
    !29 Trace a FibonacciNumber fib(2): 2 == 0 ? No; 2 == 1? No. fib(2) = fib(1) + fib(0) fib(1): 1== 0 ? No; 1 == 1? Yes. fib(1) = 1; return fib(1); fib(0): 0 == 0 ? Yes. fib(0) = 0; return fib(0); fib(2) = 1 + 0 = 1; return fib(2); fib(4) = fib(3) + fib(2) = 2 + 1 = 3; return fib(4);
  • 30.
    !30 Example 4: Fibonaccinumber w/o recursion //Calculate Fibonacci numbers iteratively //much more efficient than recursive solution int fib(int n) { int f[100]; f[0] = 0; f[1] = 1; for (int i=2; i<= n; i++) f[i] = f[i-1] + f[i-2]; return f[n]; }
  • 31.
    !31 Fibonacci Numbers Fibonacci numberscan also be represented by the following formula.
  • 32.
    !32 Example 5: BinarySearch Search for an element in an array !Sequential search !Binary search Binary search !Compare the search element with the middle element of the array !If not equal, then apply binary search to half of the array (if not empty) where the search element would be. see applet
  • 33.
    !33 Binary Search withRecursion // Searches an ordered array of integers using recursion int bsearchr(const int data[], // input: array int first, // input: lower bound int last, // input: upper bound int value // input: value to find )// output: index if found, otherwise return –1 { //cout << "bsearch(data, "<<first<< ", last "<< ", "<<value << "); "<<endl; int middle = (first + last) / 2; if (data[middle] == value) return middle; else if (first >= last) return -1; else if (value < data[middle]) return bsearchr(data, first, middle-1, value); else return bsearchr(data, middle+1, last, value); }
  • 34.
    !34 Binary Search int main(){ const int array_size = 8; int list[array_size]={1, 2, 3, 5, 7, 10, 14, 17}; int search_value; cout << "Enter search value: "; cin >> search_value; cout << bsearchr(list,0,array_size-1,search_value) << endl; return 0; }
  • 35.
    !35 Binary Search w/orecursion // Searches an ordered array of integers int bsearch(const int data[], // input: array int size, // input: array size int value // input: value to find ){ // output: if found,return // index; otherwise, return -1 int first, last, upper; first = 0; last = size - 1; while (true) { middle = (first + last) / 2; if (data[middle] == value) return middle; else if (first >= last) return -1; else if (value < data[middle]) last = middle - 1; else first = middle + 1; } }
  • 36.
    !36 Recursion General Form Howto write recursively? int recur_fn(parameters){ if(stopping condition) return stopping value; // other stopping conditions if needed return function of recur_fn(revised parameters) }
  • 37.
    !37 Example 6: exponentialfunc How to write exp(int numb, int power) recursively? int exp(int numb, int power){ if(power ==0) return 1; return numb * exp(numb, power -1); }
  • 38.
    !38 Example 6: numberof zero Write a recursive function that counts the number of zero digits in an integer zeros(10200) returns 3. int zeros(int numb){ if(numb==0) // 1 digit (zero/non-zero): return 1; // bottom out. else if(numb < 10 && numb > -10) return 0; else // > 1 digits: recursion return zeros(numb/10) + zeros(numb%10); } zeros(10200) zeros(1020) + zeros(0) zeros(102) + zeros(0) + zeros(0) zeros(10) + zeros(2) + zeros(0) + zeros(0) zeros(1) + zeros(0) + zeros(2) + zeros(0) + zeros(0)
  • 39.
    !39 Problem Solving UsingRecursion Let us consider a simple problem of printing a message for n times. You can break the problem into two subproblems: one is to print the message one time and the other is to print the message for n-1 times. The second problem is the same as the original problem with a smaller size. The base case for the problem is n==0. You can solve this problem using recursion as follows: void nPrintln(char * message, int times) { if (times >= 1) { cout << message << endl; nPrintln(message, times - 1); } // The base case is n == 0 }
  • 40.
    !40 Think Recursively Many ofthe problems can be solved easily using recursion if you think recursively. For example, the palindrome problem can be solved recursively as follows: bool isPalindrome(const char * const s) { if (strlen(s) <= 1) // Base case return true; else if (s[0] != s[strlen(s) - 1]) // Base case return false; else return isPalindrome(substring(s, 1, strlen(s) - 2)); }
  • 41.
    !41 Recursive Helper Methods Thepreceding recursive isPalindrome method is not efficient, because it creates a new string for every recursive call. To avoid creating new strings, use a helper method: bool isPalindrome(const char * const s, int low, int high) { if (high <= low) // Base case return true; else if (s[low] != s[high]) // Base case return false; else return isPalindrome(s, low + 1, high - 1); } bool isPalindrome(const char * const s) { return isPalindrome(s, 0, strlen(s) - 1); }
  • 42.
    !42 Example 7: Towersof Hanoi Only one disc could be moved at a time A larger disc must never be stacked above a smaller one One and only one extra needle could be used for intermediate storage of discs see applet
  • 43.
    !43 Towers of Hanoi voidhanoi(int from, int to, int num) { int temp = 6 - from - to; //find the temporary //storage column if (num == 1){ cout << "move disc 1 from " << from << " to " << to << endl; } else { hanoi(from, temp, num - 1); cout << "move disc " << num << " from " << from << " to " << to << endl; hanoi(temp, to, num - 1); } }
  • 44.
    !44 Towers of Hanoi intmain() { int num_disc; //number of discs cout << "Please enter a positive number (0 to quit)"; cin >> num_disc; while (num_disc > 0){ hanoi(1, 3, num_disc); cout << "Please enter a positive number "; cin >> num_disc; } return 0; }
  • 45.
  • 46.
    !46 bool empty(int t[],int row, int col) { for( int j = 0; j < row; j++) { if (t[j] == col) //same column return false; if (abs(t[j] - col) == (row - j)) //on cross line return false; } return true; } bool queens(int t[], int row, int col) { if (row == SIZE) // found one answer return true; for (col = 0; col <SIZE; col++) { t[row] = col; if (empty(t, row, col) && queens(t, row +1, 0)) return true; } return false; }
  • 47.
    void print(int t[]){ //print solution for(int i = 0; i < SIZE; i++) { for(int j = 0; j < SIZE; j++) { if (j == t[i]) cout << " Q "; else cout << " _ "; } cout << endl; } } int main() { int t[SIZE]={0}; for (int i= 0; i <SIZE; i++){ t[0] = i; //on first row, Queen on different column cout << endl << endl <<"i is: " << i << endl; if (queens(t, 1,0)) print(t); } }