Recursion is one of the basic modes for describing a process in a program computing process. we must be very careful before discussing the recursion problem, because recursion contains two aspects: one is a recursive computing process, the first is a recursive process, the latter is a fact in syntax, and the former is a conceptual computing process. In fact, we may use loops in the program.

I recently re-read and write some thoughts. The following are some of the recursive and iterative computing knowledge.

Recursion

Recursion is one of the basic modes for describing a process in a program computing process. we must be very careful before discussing the recursion problem, because recursion contains two aspects: one is a recursive computing process, the first is a recursive process, the latter is a fact in syntax, and the former is a conceptual computing process. In fact, we may use loops in the program.

**Recursive calculation process**As we often say**Recursive process**Not the same thing.

**Recursive process:**"When we talk about a process as recursion, we discuss a fact in the syntax form, indicating that the process itself is referenced in the definition of this process (either directly or indirectly ."
**Recursive calculation process:**"When a computing process has a certain pattern (for example, linear recursion), we are talking about the progress of this computing process, rather than the syntax format written in the corresponding process ."

We generally like to use the Fibonacci series as an example when discussing recursion. The Fibonacci algorithm is also very simple. the algorithm is as follows:

def Fib(n): if (n < 1): return 0 elif (n <= 2): return 1 else: return Fib(n-1)+Fib(n-2)

Example of a specific C language.

# Include "stdio. h "# include" math. h "int factorial (int n); int main (void) {int I, n, rs; printf (" Enter the Fibonacci number n :"); scanf ("% d", & n); for (I = 1; I <= n; I ++) {rs = factorial (I ); printf ("% d", rs);} return 0;} // recursive calculation process int factorial (int n) {if (n <= 2) {return 1 ;} else {return factorial (n-1) + factorial (n-2 );}}

Program running:

Enter the Fibonacci number n: 121 1 2 3 5 8 13 21 34 55 89 144

Suppose n = 6, then the calculation process is to calculate Fib (6), Fib (5) and Fib (4), and so on, as shown in the following code:

We can see that the process is like an inverted tree. this method is called tree recursion and linear recursion. This recursive method is very straightforward and has a good understanding of its computing process. generally, many people write recursion in this way subconsciously.

However, the disadvantage is obvious. from the computing process, we can see that after a lot of redundant computing and a large number of call stacks are consumed, this consumption increases exponentially, it is often said that the call stack is easy to consume in a very short recursive process, most of which is caused by linear recursion. The process of linear recursion can be clearly described. the process of expansion and collapse can be clearly seen:

(factorial (6))(6 * factorial (5))(6 * (5 * factorial (4)))(6 * (5 * (4 * factorial (3))))(6 * (5 * (4 * (3 * factorial (2)))))(6 * (5 * (4 * (3 * (2 * factorial (1))))))(6 * (5 * (4 * (3 * (2 * 1)))))(6 * (5 * (4 * (3 * 2))))(6 * (5 * (4 * 6)))(6 * (5 * 24))(6 * 120)720

Iteration

It corresponds to the recursive computing process, which is an iterative computing process.

In addition to this recursive method, there is another method to implement recursion. the above Fibonacci number is also used as an example. this time we will not start with the definition of Fibonacci, we can start from the process of producing a series normally. if we are 0, 1, we can simply return the result directly. the subsequent calculation process is Accumulation. we need to maintain the state in the recursive process, this state requires three numbers, that is, the last two numbers and the number of iterations. Therefore, we define the method as follows:

def Fib(n,b1=1,b2=1,c=3): if n <= 2: return 1 else: if n==c: return b1+b2 else: return Fib(n,b1=b2,b2=b1+b2,c=c+1)

This method maintains the state of the last calculation in every recursive process, so it is called "linear iteration process", also known as tail recursion. Since each step of computing is in the state, redundant computing is eliminated, so the efficiency of this method is significantly higher than that of the previous one. the calculation process is as follows:

fib(6)fib 0,0,1fib 0,1,2fib 1,2,3fib 2,3,4fib 3,5,5fib 5,8,6

The two recursive methods can be converted. any recursive process that describes the intermediate computing process through a fixed number of states can be expressed through linear iteration.

"The iterative computing process is a computing process described by a fixed number of state variables, and there is a set of fixed rules that describe the transition from a state to the next state, the update method of these variables also ends the detection, which describes the conditions that the calculation process should stop."

Taking the factorial of n as an example, the recursive write is:

// Function factorial (n) {if (n = 1) {return 1;} return n * f (n-1 );}

It is also the factorial for calculating n, and can also be designed as follows:

// Function factorial (n) {return factIterator (1, 1, n);} function factIterator (result, counter, maxCount) {if (counter> maxCount) {return result;} return factIterator (counter * result), counter + 1, maxCount );}

The execution process is as follows:

(factorial (6))(factIterator(1, 1, 6))(factIterator(1, 2, 6))(factIterator(2, 3, 6))(factIterator(6, 4, 6))(factIterator(24, 5, 6))(factIterator(120, 6, 6))(factIterator(720, 7, 6))

Although the factIterator method calls itself, all the things required during its execution are result, counter, and maxCount. Therefore, it is an iterative computing process. This process does not need to add storage when it continues to call itself. Such a process is called tail recursion.

Tail recursion can also be replaced by loops:

function fib(n){ var a=0, b=1; for(var i=0;i<=n;i++){ var temp = a+b; a = b; b = temp; } return b;}

Recursion and iteration

The recursive computing process is more natural and straightforward. it helps us understand and design programs. To plan an iterative computing process, you need to design various state variables and find the iteration rules. not all recursive computing processes can be easily organized into iterative computing processes.

However, recursive computing is less efficient than iterative computing.

The recursive calculation process for factorial calculation above is linear recursion, and the increase in the number of steps is proportional to the input n. That is to say, the increase in the steps required in this process is O (n), and the increase in space demand is also O (n ). For the factorial of iteration, the number of steps is O (n), and the space is O (1), that is, the constant.

Let's look at the recurrence and iteration of the Fibonacci series.

Recursive calculation process:

// Recursive calculation process function fib (n) {if (n <= 1) {return n;} return fib (n-1) + fib (n-2 );}

Iterative computing process and tail recursion:

// Iterative calculation process, tail recursion function fib (n) {return fibIterator (1, 0, n);} function fibIterator (a, B, counter) {if (counter = 0) {return B;} return fibIterator (a + B), a, counter-1 )}

The recursive calculation process of the Fibonacci series is tree recursion. you can see it by drawing its expansion method. The number of steps increases exponentially. this is an exaggerated growth mode. Each increase of 1 will lead to a constant doubling of the resources used. In the iterative computing process, the step growth is still O (n), linear growth, that is, doubling the scale, and doubling the resources used.

Sometimes to reduce recursion, we need to reduce the recursive calculation process and replace it with a more efficient method.

We also found that the tail recursion process is basically equivalent to the Loop. we can easily replace the tail recursion process with the loop, therefore, many languages provide compilation-level optimization for tail recursion, that is, converting tail recursion into cyclic code during compilation. However, it makes sense for languages that do not provide tail recursion optimization. for example, python's default call stack length is 1000. if linear recursion is used, it will soon consume light, but tail recursion will not, for example, the Fib function of tail recursion can be called with Fib (1001) and run fast. the Stack Overflow occurs only when Fib (1002) is used. However, when the linear recursion method is used to calculate n = 30, the speed will obviously become slower, and the speed will basically go down if it is more than 40.

Here I have no intention of comparing the advantages and disadvantages of the two methods. maybe there is a gap in linear regression, but it is very readable, almost equivalent to the direct description of the formula, therefore, you can choose based on the computing scale.

Additional reading

The topic list of this article is as follows:

- Recursive: recursive thinking
- Recursion: two conditions that must be met by recursion
- Recursion: recursive determination of string-to-text phenomena
- Recursive: recursive implementation of binary search algorithms
- Recursion: the efficiency of recursion
- Recursion: recursion and loop
- Let's talk about recursion: Is loop and iteration the same thing?
- Recursive computing and iterative computing
- On Recursion: Learn about tail recursion from Fibonacci
- Recursive: Tail recursion and CPS
- Recursion: add more knowledge about Continuation.
- Recursion: Tail recursion in PHP and its optimization
- Recursion: Tail recursion optimization from the perspective of Assembly

This article is available at http://www.nowamagic.net/librarys/veda/detail/2280.