When learning to program, teachers always do not recommend recursion, some books have so far suggested. But the application of recursion in binary tree is graceful and slightly complicated. So it is necessary to understand that the nature of recursion is to divide and conquer. Reduce the scale of problems.
Why use recursion
The basic algorithm for estimating the most confusing mind in programming is recursion. Many times we see that a complex recursion is a bit of a time-consuming problem, especially when the concept of a model is unclear, and it is more difficult to design a recursion yourself.
A lot of people do not understand recursion (today in CSDN see a beginner's message), always think that recursion is completely unnecessary, with the loop can be achieved, in fact, this is a very superficial understanding. Because recursion in the program can be swept not because of his cycle, we all know that recursion is divided into two steps, recursion and return, then you can know recursion for space performance, is simply commit, this for the pursuit of space-time perfect person, simply can not accept, if recursion is just a loop, estimated now we can not see recursion. Recursion now exists because recursion can produce an infinite loop, which means that it is possible to generate 100 or 10000 layers for loops. For example, for a string to be fully arranged, the string length is variable, then if you use the loop to implement, you will find that you do not write, this time to call recursion, and in the recursive model can also use branch recursion, such as for loop and recursive nesting, or this section enumerates several recursive stepping expressions, Each one forms a recursive. using inductive method to understand recursion
Mathematics is not bad for us, the first reaction is the recursive mathematical model is what. After all, we are much more adept at modeling problems than we do with code modeling. (Of course, if the problem is clear to the person can also direct resume recursive model, the use of digital modeling intermediary is for those who are not very clear about the problem)
Observing recursion, we will find that the recursive mathematical model is actually inductive, which is the most common in the high School series. Recall the inductive method.
Inductive method is applied to solve a problem to solve his sub-problem, and his sub-problem becomes sub-problem, and we found that these problems are actually a model, that is, there is the same logical induction processing items. Of course there is an exception, that is, which of the recursive end of the processing method does not apply to our inductive processing items, of course, we can not apply, otherwise we will be infinite recursion. This leads to an inductive endpoint and an expression for direct solution. If the use of a list to describe the induction is: Step expression: The problem becomes a sub-problem of the expression end condition: When can no longer be used to solve the expression directly with the step expression: the expression logic can be calculated directly in the end of the return value of the logical induction: applicable to all non-applicable to the end of the problem of processing, Of course, the above step expression is actually contained in the face.
This is actually the end, and the recursion comes out. The general form of the recursive algorithm:
|Func (mode)//call itself, recursive
The most typical is the n! algorithm, which is the most persuasive. Understand the idea of recursion and use of the scene, the basic can be designed by themselves, of course, and other algorithms to use, but also need to continue to practice and summary.
|printf ("Please enter the number of factorial to be calculated n:");
|Recursive calculation process
|return n * factorial (n-1);
The recursion of factorial is relatively simple, it is not unfolded here. Another example of two recursion
Returns the depth of a binary tree:
|Return (A>B)? (a+1):(b+1);
Determine whether a binary tree is balanced:
|int Right=isb (t.right);
|if (left >=0 && right >=0 && left-right <= 1 | | left-right >=-1)
|Return (left < right)? (right + 1): (left + 1);
The first algorithm is better understood, but the second one is not so well understood. The idea of the first algorithm is that if the tree is empty, it returns 0, otherwise the depth of the left tree is obtained, then the depth of the right number is obtained, and then the value of the two values is compared which is whichever is +1. And the second algorithm, first should understand the function of the ISB function, it returns 0 for the empty tree, for the balance tree to return the depth of the tree, for the unbalanced tree returns-1. Understand the function of functions and then see the code is much more clear, as long as a function returned 1, the entire function will return-1. (The specific process as long as a careful look at the understanding)
For recursion, the best way to understand it is to understand it from the functional meaning of the function. Understand how a problem is broken down into its sub-problems, so that the recursive function code is understood. Here is a misunderstanding (I have been in it), is through the analysis of the stack, a function of the call process, output results to analyze the recursive algorithm. This is very undesirable, this will only stun themselves, in fact, the recursive nature is also a function of the call, the function of the call is itself or not the fact that there is no difference. Some temporary information is always saved to the stack when the function is called, and the stack is just for the function to return correctly, that's all. As long as we know that recursion leads to a lot of function calls, a lot of stack operations are possible. Summary
The basic idea of recursion is to transform large-scale problems into small-scale similar sub-problems to solve. When a function is implemented, because the method of solving the big problem and the method of solving the small problem are often the same method, it produces the case that the function calls itself. In addition, the problem-solving function must have an obvious end condition, so that no infinite recursion can occur.
two conditions required for recursion
Many people have a less profound understanding of recursion. Always stay in the "self-invocation" degree. This is actually just the representation of recursion (strictly speaking, even the appearance is not comprehensive, because there is recursion of the interactive call in addition to the recursion of "self-invocation"). And the idea of recursion is much more than simple.
Recursion is not a simple "call yourself", nor a simple "interactive call". It is a method and thought to analyze and solve the problem. Simply put, the idea of recursion is to break the problem down into smaller, less-sized problems with the same solution as the original problem. For example, the binary search algorithm is to keep the size of the problem smaller (half of the original problem), and the new problem has the same solution as the original problem.
Some problems using traditional iterative algorithm is difficult to solve or even no solution, and the use of recursion can be easily solved. Like the Hanoi tower problem. But the use of recursion also has its disadvantage, because it wants to make multi-layered function calls, so it will consume a lot of stack space and function call time.
Since the idea of recursion is to decompose the problem into a smaller size and have the same solution as the original problem, then is not such a problem can be solved with the recursive return. The answer is in the negative. Not all problems can be solved with a recursive return. So what kind of problem can be solved by hand. Generally speaking, the problem that can be solved by recursion must satisfy two conditions: the problem scale can be narrowed by recursive call, and the new problem has the same form as the original problem. There is a simple situation in which recursion can be exited in a simple context.
If a problem does not meet the above two conditions, then it cannot be resolved by recursion.
To facilitate understanding, or to take the Fibonacci sequence: The value of the nth item of the Fibonacci sequence.
This is a classic question, and when it comes to recursion, it must be mentioned. The Fibonacci sequence is defined as: F (0) = 0, f (1) = 1, n > 1, f (n) = f (n-1) + f (n-2)
This is an obvious problem that can be solved by recursion. Let's look at how it satisfies the two conditions of recursion: For a n>2, f (n) requires only F (n-1) and F (n-2), that is, the problem of size n is transformed into a smaller problem; for n=0 and N=1, there is a simple situation: f (0) = 0, f (1) = 1.
Therefore, we can easily write a recursive procedure that calculates the nth item of the Fibonacci sequence:
|return f (n-1) + f (n-2);
When writing a recursive call to a function, be sure to write the judgment of the simple situation in the first place, in order to ensure that the function call in a simple situation to check the time to abort recursion, otherwise, your function may never cease to be there recursive call.
The phenomenon of string palindrome
There are some ideas about recursion, and some conceptual understandings, and here's a try to solve some problems with recursion. Like a palindrome.
A palindrome is a string, which is the same as reading and reading back. For example, Level,eye are palindrome. Using an iterative method, you can quickly determine whether a string is a palindrome. How to do it with a recursive approach.
First, we need to consider the two conditions of recursion: first: Whether the problem can be decomposed into the same form but smaller. Second: If there is such a decomposition, then there is a simple situation of this decomposition.
First look at the 1th, whether there is a conditional decomposition. It is easy to find that if a string is a palindrome, there must be a smaller palindrome inside it. For example, Eve in level is also a palindrome. Moreover, we notice that the first character of a palindrome and the last one must be the same.
So, naturally, we have this approach:
First of all, to determine whether a given string is equal or not, if it is equal, the string is determined to remove the first and the first character is a palindrome, if not equal, then the string is not a palindrome.
Note that we have successfully scaled down the size of the problem, and the string that removes the end-to-end character is certainly smaller than the original string.
Then look at the 2nd, whether there is a simple situation of this decomposition. Simple situations are necessary when using recursion, or your recursive program may go into endless calls.
For palindrome problems, it is easy to find that a string with only one character must be a palindrome, so only one character is a simple situation, but it is not the only simple situation, because the empty string is also a palindrome. In this way, we have two simple scenarios for palindrome problems: The number of characters is 1 and the number of characters is 0.
Well, two conditions are satisfied, based on the above analysis, we can easily write a solution to solve the problem of the recursive implementation of the method:
|printf ("Please enter a string to judge Palindrome:");
|n = (int) strlen (str);
|rs = Is_palindereme (str, n);
|int Is_palindereme (char *str, int n)
|printf ("Length:%d \ n", n.);
|printf ("%c-----%c\n", str, str[n-1]);
|if (n = = 0 | | n = = 1)
|printf ("%d,%d\n", str, str[n-1]);
|Return ((str = = str[n-1])? Is_palindereme (Str+1, n-2): 0);