You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: recursion/README.md
+9-11Lines changed: 9 additions & 11 deletions
Original file line number
Diff line number
Diff line change
@@ -3,11 +3,11 @@
3
3
Recursion is a computational technique that implements a [divide-and-conquer](../dnc) approach to problem-solving by breaking down a complex problem into smaller sub-problems. It consists of two components:
4
4
5
5
* One or more base cases that provide output for simple inputs and terminate recursion
6
-
* A recursive case that combines the outputs obtained from recursive function calls to generate a solution for the original problem.
6
+
* A recursive case that combines the outputs obtained from recursive function calls to generate a solution for the original problem
7
7
8
8
Although recursions enhance code readability, they are usually inefficient and challenging to debug. Consequently, unless they provide a more efficient solution to a problem, such as in the case of [quicksort](../dnc/quick_sort_test.go), they are generally not preferred.
9
9
10
-
During execution, a program typically stores function variables in a memory area known as the stack before executing recursion. The recursive function may assign different values to the same variables during each recursion. When the recursion ends, the stack pops and remembers the values. However, the stack will grow with each call if recursion continues indefinitely, causing the familiar stack overflow error. Since recursion employs the stack to execute, every recursive problem can be converted into an iterative one. This transformation, however, typically leads to more complex code and may require a [stack](../stack).
10
+
During execution, a program typically stores function variables in a memory area known as the stack before executing recursion. The recursive function may assign different values to the same variables that are stored separately for each call during each recursion. When the recursion ends, the stack pops and remembers the values. However, the stack will grow with each call if recursion continues indefinitely, causing the familiar stack overflow error. Since recursion employs the stack to execute, every recursive problem can be converted into an iterative one. This transformation, however, typically leads to more complex code and may require a [stack](../stack).
11
11
12
12
## Implementation
13
13
@@ -16,9 +16,7 @@ The computation of the nth Fibonacci number can be achieved with recursion. For
16
16
```Go
17
17
package main
18
18
19
-
import (
20
-
"fmt"
21
-
)
19
+
import"fmt"
22
20
23
21
funcmain() {
24
22
fori:=1; i <= 10; i++ {
@@ -36,9 +34,9 @@ func fibonacci(n int) int {
36
34
37
35
When formulating recursive algorithms, it is essential to consider the following four rules of recursion:
38
36
39
-
1. It is imperative to establish a base case, or else the program will terminate abruptly
40
-
2. The algorithm should progress toward the base case at each recursive call.
41
-
3. Recursive calls are presumed effective; thus, traversing every recursive call and performing bookkeeping is unnecessary.
37
+
1. It is imperative to establish a base case, or else the program keep recursing and terminate abruptly after running out of stack memory
38
+
2. The algorithm should progress toward the base case at each recursive call
39
+
3. Recursive calls are presumed effective; thus, traversing every recursive call and performing bookkeeping is unnecessary
42
40
4. Use memoization, a technique that prevents redundant computation by caching previously computed results, can enhance the algorithm's efficiency.
43
41
44
42
## Complexity
@@ -47,9 +45,9 @@ Recursions are often inefficient in both time and space complexity. The number o
47
45
48
46
There are a few different ways of determining the time complexity of recursive algorithms:
49
47
50
-
1. Recurrence Relations: This approach involves defining a recurrence relation that expresses the algorithm's time complexity in terms of its sub-problems' time complexity. For example, for the recursive Fibonacci algorithm, the recurrence relation is T(n) = T(n-1) + T(n-2) + O(1), where T(n) represents the time complexity of the algorithm for an input of size n.
51
-
2. Recursion Trees: This method involves drawing a tree to represent the algorithm's recursive calls. The algorithm's time complexity can be calculated by summing the work done at each level of the tree. For example, for the recursive factorial algorithm, each level of the tree represents a call to the function with a smaller input size, and the work done at each level is constant.
52
-
3. Master Theorem: This approach is a formula for solving recurrence relations that have the form T(n) = aT(n/b) + f(n). The Master Theorem can be used to quickly determine the time complexity of some [Divide-and-conquer](../dnc) algorithms.
48
+
1. Recurrence Relations: This approach involves defining a recurrence relation that expresses the algorithm's time complexity in terms of its sub-problems' time complexity. For example, for the recursive Fibonacci algorithm, the recurrence relation is T(n) = T(n-1) + T(n-2) + O(1), where T(n) represents the time complexity of the algorithm for an input of size n
49
+
2. Recursion Trees: This method involves drawing a tree to represent the algorithm's recursive calls. The algorithm's time complexity can be calculated by summing the work done at each level of the tree. For example, for the recursive factorial algorithm, each level of the tree represents a call to the function with a smaller input size, and the work done at each level is constant
50
+
3. Master Theorem: This approach is a formula for solving recurrence relations that have the form T(n) = aT(n/b) + f(n). The Master Theorem can be used to quickly determine the time complexity of some [Divide-and-conquer](../dnc) algorithms
53
51
54
52
The space complexity of recursive calls is affected by having to store a copy of the state and variables in the stack with each recursion.
0 commit comments