Tail recursion is a programming technique. A recursive function is a function that calls its own function. if the result returned by a recursive function is directly returned, it is called tail recursion. Recursive functions at the end can be used to convert algorithms into function programming languages. In addition, they are easily optimized into common loops from the compiler perspective. This is because from the computer fundamentals, all cycles are implemented by repeatedly moving to the beginning of the code.

Tail recursive is a form of recursion. In short, recursion means that the function calls itself. The difference between tail recursion and recursion can only be reflected in parameters.

The syntax of the tail recursion wiki is as follows:

Tail recursion is a programming technique. A recursive function is a function that calls its own function. if the result returned by a recursive function is directly returned, it is called tail recursion. Recursive functions at the end can be used to convert algorithms into function programming languages. In addition, they are easily optimized into common loops from the compiler perspective. This is because from the computer fundamentals, all cycles are implemented by repeatedly moving to the beginning of the code. If there is tail delivery, you only need to stack one stack, because the computer only needs to change the function parameters and then call them again. The main purpose of tail recursion is to optimize it. for example, in Scheme, it is specified that tail recursion must be optimized. It can be seen that the role of tail recursion is very dependent on the specific implementation.

Let's start with the simple Fibonacci to understand tail recursion.

Use ordinary recursion to calculate the series of Fibonacci:

# 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); rs = factorial (n); printf ("% d \ n", rs); return 0 ;} // recursive int factorial (int n) {if (n <= 2) {return 1;} else {return factorial (n-1) + factorial (n-2 );}}

The running result of the programmer is as follows:

Enter the Fibonacci number n: 206765 Process returned 0 (0x0) execution time: 3.502 sPress any key to continue.

It also takes 3.502 seconds under the i5 CPU.

Next we will look at how to implement the Fibonacci number with tail recursion.

# 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); rs = factorial_tail (n, 1, 1); printf ("% d", rs); return 0 ;} int factorial_tail (int n, int acc1, int acc2) {if (n <2) {return acc1;} else {return factorial_tail (n-1, acc2, acc1 + acc2 );}}

The running result of the programmer is as follows:

Enter the Fibonacci number n: 206765 Process returned 0 (0x0) execution time: 1.460 sPress any key to continue.

More than doubled faster. Of course, this is incomplete statistics. if you are interested, you can calculate a large number of values on your own. here we only introduce tail recursion.

We can print the execution process of the program, and add the following print statement to the function:

int factorial_tail(int n,int acc1,int acc2){ if (n < 2) { return acc1; } else { printf("factorial_tail(%d, %d, %d) \n",n-1,acc2,acc1+acc2); return factorial_tail(n-1,acc2,acc1+acc2); }}

Program running result:

Enter the Fibonacci number n: 10factorial_tail (9, 1, 2) factorial_tail (8, 2, 3) factorial_tail (7, 3, 5) factorial_tail (6, 5, 8) factorial_tail (5, 8, 13) factorial_tail (4, 13, 21) factorial_tail (3, 21, 34) factorial_tail (2, 34, 55) factorial_tail (1, 55, 89) 55 Process returned 0 (0x0) execution time: 1.393 sPress any key to continue.

From the above debugging, we can clearly see the calculation process of tail recursion. Acc1 is the nth number, and acc2 is the sum of the nth and nth + 1. this is the essence of the "iteration" we mentioned earlier, the calculation result is involved in the next calculation, which reduces a lot of repeated computations.

Fibonacci (n-1, acc2, acc1 + acc2) is actually a magic pen. the layers of stacks generated by simple recursion are exponentially increasing like binary trees, but now the layers of stacks are like arrays, it is really amazing to change to linear growth. In summary, it is also very simple. Originally, the stack was expanded first, and then the calculation results were collected while the side was being called, but now it is computed by parameters while calling itself.

Summary

The essence of tail recursion is to cache the results of a single calculation and pass them to the next call, which is equivalent to automatic accumulation.

In imperative languages such as Java, tail recursion is rarely used, because we can solve it with loops directly. In functional languages, tail recursion is an artifact that relies on loop implementation.

Many may wonder why tail recursion is also recursive, but does not cause stack overflow? Because the compiler usually optimizes tail recursion. The compiler will find that there is no need to store stack information at all, so it will directly clear the relevant stack at the end of the function.

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/2325.