Explore recursive algorithms, their implementation, and when to use them effectively. Understand the power and limitations of recursion in solving complex problems.
Recursion is a programming technique where a function calls itself to solve a problem by breaking it down into smaller instances of the same problem. For recursion to work properly, it must have:
Recursive solutions are often elegant and can clearly represent the problem structure, especially for tasks that have a natural recursive definition, like traversing tree structures or calculating factorial values.
The Fibonacci sequence is a classic example for demonstrating recursion. Each number in the sequence is the sum of the two preceding ones, typically starting with 0 and 1.
The sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ...
public int fibonacciRecursive(int n) {
// Base case
if (n == 0 || n == 1) {
return n;
}
// Recursive case
return fibonacciRecursive(n - 2) + fibonacciRecursive(n - 1);
}
public int fibonacciIterative(int n) {
if (n == 0 || n == 1) {
return n;
}
int previousPreviousNumber = 0;
int previousNumber = 1;
int currentNumber = 0;
for (int i = 2; i <= n; i++) {
currentNumber = previousPreviousNumber + previousNumber;
previousPreviousNumber = previousNumber;
previousNumber = currentNumber;
}
return currentNumber;
}
public long factorial(int n) {
// Base case
if (n == 0 || n == 1) {
return 1;
}
// Recursive case
return n * factorial(n - 1);
}
public void inOrderTraversal(TreeNode node) {
// Base case
if (node == null) {
return;
}
// Recursive cases
inOrderTraversal(node.left); // Process left subtree
System.out.println(node.value); // Process current node
inOrderTraversal(node.right); // Process right subtree
}