See the recursion tree
Watch calls expand
See values return
Understand call stack
Click "Visualize" to see the recursion unfold.
When the recursive call is the last operation, some engines can optimize to prevent stack growth.
// Tail recursive version
function factorial(n, acc = 1) {
if (n <= 1) return acc;
return factorial(n - 1, n * acc);
}
// Stack doesn't grow with n
Naive Fibonacci makes redundant calls, leading to O(2^n) time complexity.
// Bad: O(2^n) - many duplicate calls
function fib(n) {
if (n <= 1) return n;
return fib(n-1) + fib(n-2);
}
// Use DP/memoization instead!
Use recursion for naturally recursive structures (trees, graphs) and when it makes code clearer. Use iteration when performance is critical or stack depth is a concern.
Use an explicit stack data structure. Push items instead of making recursive calls, and pop to process. This simulates the call stack manually.
Memoization caches results of expensive function calls. For recursive functions with overlapping subproblems (like Fibonacci), it can reduce complexity from exponential to linear.