Episode: About recursion

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

1 overview

Loop and recursion is the most common method of the control process in the algorithm, the cycle from needless to say, as long as the computer language has been learned, it is necessary to speak of this control structure, and for recursion, we can also write very beautiful (tree algorithm and graph algorithm using recursive scene is also very much).

The benefits of recursion are also obvious, the code is small and easy to maintain. However, recursion is not a master key, especially when the running environment has limited memory space and requires high performance scenarios. The following first introduces the principle of recursive operation, and then illustrates the cost of recursion, then explains how recursion is converted into a loop and its limitations, and finally summarizes this article.

2 Operating principle of recursion

Recursive refers to the recursive function, what is the principle of recursive function execution in the program (von Neumann system)? This is the key to realize the efficiency of recursive function execution. In the following example, we illustrate the process of recursive function execution by constructing Fibonacci sequence. The recursive function for constructing the Fibonacci sequence (Golang implementation) is as follows:
fun Fib(n int) int{ ret : = 0 if n == 0 || n == 1 { // 1 ret = 1 // 2 } ret = Fib(n - 1) + Fib(n - 2) // 3 return ret}
Children who have learned the principles of compiling are aware that functions run on stacks (pairs, which are the stacks that children learn on data structures), if the principle of N=4,FIB (4) shows 1:


Figure 1:fib (4) dynamic

FIB (4) is required, the FIB (3) must be sought on the stack (FIB (3) is required, and the FIB (2) and FIB (1) are required for the stack, and the FIB (2) is asked to continue on the stack for FIB (1) and fib (0)) and FIB (2) (like FIB (3)) Such a recursive algorithm, must be on the stack to record the local variables inside the function, pass parameters, return address (until the end of the call to return to where) and the previous stack of EBP and BP (Restore the caller stack), and frequent stack into the stack is a need for overhead, although the single-entry stack is not expensive, but if required fib (1000 Such a function, I am afraid the general single-machine estimate to run a few 10 minutes or even half a day (in the author's Mac Ben ran for a few minutes did not come out, directly to the process killed, can not endure).

In order to have an intuitive feel, the author deliberately made a simple experiment (see my Git), respectively, with recursive and non-recursive solutions for FIB (Ten), FIB (50), fib (+), fib (+), the result of the operation, as shown in:


Figure 2: Recursive and non-recursive test results


As can be seen from the running results, when the n value is small (<10), the recursive run time is less than the non-recursive run time (the reason should be non-recursive allocation slice need to occupy a relatively long time, this kind of writing some mentally, actually only need two intermediate variables, Similar to the idea of using the third variable to realize two-variable value exchange, when n>=20, the non-recursive run time is much lower than the recursive run time, the greater the N, the more efficient non-recursive relative recursion.

Of course, non-recursive efficient operation is not without cost, compared to recursive functions, writing code is more difficult and more difficult to maintain.

3 Recursive turn non-recursive

So how do you convert a recursive function to a non-recursive function? are all recursive functions converted to non-recursive functions?

First it must be clarified what kind of recursion, recursion has two, one is one-way recursion, similar to FIB (n) This is a typical one-way recursion (FIB (n)->fib (n-1)->fib (n-2)->...->FIB (1)) Another kind of recursion ( may be called interactive recursion, not necessarily accurate ) in the form of: F1 (n), F2 (n), F1 (n-1), F2 (n-1), ...

In one-way recursion, the tail recursion is the most efficient, and the tail recursion refers to the function that ends with the call itself. The FIB (n) mentioned above is not a tail recursion, but it can be converted to a recursive function as follows (not to compare the efficiency of tail recursion and non-recursive notation):
fun TailFib(n, f1, f2 int) int{ if n < 2{ return f1 } return TailFib(n-1, f2, f1 + f2)}
The corresponding non-recursive notation is:
func NotRecursion(n, f1, f2 int) int{ if n < 2{ return 1; } i := 0 for i <= n { f2 = f1 + f2 f1 = f2 - f1 } return f1}
Tail recursion is the most efficient in recursive functions, because when a recursive call returns, it returns to the next statement of the previous recursive call statement, which is exactly the end of the program, so the return address can not be saved in the recursive work stack, and other parameters and local variables are no longer needed except for the return value and the reference value. It is easy to write non-recursive algorithms according to the logic of tail recursion.

For interactive recursion, the form is relatively complex, and may be inadvertently written out when it comes to specific projects. Reciprocal recursion relative to one-way recursion, it is difficult to write the corresponding non-recursive function directly, need to extract F1 (n), F2 (n), F1 (n-1), F2 (n-1), ... Inside the F1 (i)->f2 (i)->f1 (i-1)->f2 (i-1), the common logic in this is that one iteration can express the transformations therein. If it is difficult to extract, the most straightforward way is to simulate the stack out of the process, extract the parameters inside the characteristics, set up a loop iteration (next think of an example).

4 Summary

Recursion is a common method in the algorithm, especially in the structure of tree and graph, and understanding the principle of recursive operation is the key to write efficient code. For scenarios with high efficiency requirements, you can try to write a non-recursive version. Generally speaking, recursive code is small, easy to maintain, non-recursive code understanding maintenance slightly difficult, but the implementation of relatively high efficiency.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.