C language recursive analysis and C language Recursion
Ideas
It describes the thought process from question to question variation:
Overview
This article uses the number conversion as an example to analyze recursion. It mainly analyzes the recursive process from multiple perspectives and discusses the characteristics and usage of recursion.
Introduction
When a program is completed, it suddenly wants to convert any number in hexadecimal format, so it involves at least the following parameters:
Recursion 1. Meaning of Recursion
Recursion is a recursive function. Recursive functions call their own functions directly or indirectly.
For example:
Procedure 1: btoa. c
1/* 2 ** accepts an integer value (unsigned), converts it to a character, and prints it. The leading zero is deleted. 3 */4 # include <stdio. h> 5 void binary_to_ascii (unsigned int value) {6 unsigned int quotient; 7 quotient = value/10; 8 if (quotient! = 0) 9 binary_tc_ascii (quotient); 10 putchar (value % 10 + '0'); 11}
In addition, recursion has the so-called "three conditions" and "two stages ". I will not talk about it. In practice, the conditions are naturally met.
2. recursive process analysis
Example:
Five people sit from left to right. The person on the right is two years older than the person on the left. The person on the left is 10 years older than the person on the left. Ask the rightmost person's age.
Procedure 2: age. c
1 #include <stdio.h> 2 age(int n) { 3 int c; 4 if( n == 1 ) 5 c = 10; 6 else 7 c = age( n-1 ) + 2; 8 return(c); 9 }10 11 int main() {12 printf("%d\n\n",age( 5 ) );13 return 0;14 }
Expression:
Recurrence and rollback processes:
What does this have to do with interruptions? It seems not obvious at the moment, but at first I thought of the interruption in microcomputer principles: Execution started from age (5), and then calls age (4 ), when an interruption occurs, the scene is protected first, and then recursion continues until n = 1, the interruption ends, and then layer-by-layer return, that is, the process of continuously restoring the scene.
Nested call angle:
Nested call relationship diagram:
3. Recursive Application
We have analyzed the recursive process from different perspectives. The actual application does not require you to understand the internal process of each recursion. What is important is to use the correct method.
The following are examples of improper recursive application:
In many textbooks, the calculation of factorial and Fibonacci series are used to illustrate recursion. However, recursion in the former does not provide any advantages, and the latter has very low recursion efficiency.
Let's take a look at the extreme Fibonacci number solution:
Expression:
Program 3: fig
1/* 2 ** use recursion to calculate the value of the nth Fibonacci sequence. 3 */4 5 int fibonacci (int n) {6 if (n <= 2) 7 return 1; 8 return fig (n-1) + fig (n-2 ); 9}
There is a trap: it uses recursive steps to calculateFibonacci (n-1) and fibonacci (n-2 ). However, the computation of fibonacci (n-1) will also calculate fibonacci (n-2 ). What is the extra cost?
The answer is: the cost is far more than one redundant computing: each recursive call will trigger two other recursive calls. either of these two calls will also trigger two recursive calls, the same is true for subsequent calls. In this way, the number of redundant computing increases rapidly. For example, during recursive Calculation of fibonacci (10), the value of fibonacci (3) is calculated 21 times. However, in recursive computation of fibonacci (30), the value of fibonacci (3) is calculated 317811 times. Of course, the results of these 317811 times are exactly the same, except for one of them, the rest is a waste.
Think more extreme. If you do not recursion twice in a program, but three or four times, and call itself more times, I think the program may crash.
Now let's try to replace recursion with loops:
Program 4: maid
1 int fibonacci( int n ) { 2 int result; 3 int previous_result; 4 int next_older_result; 5 result = previous_result = 1; 6 while(n > 2 ) { 7 n -= 1; 8 next_older_result = previous_result; 9 previous_result = result;10 result = previous_result + next_older_result;11 }12 return result;13 }
Okay. Now, this article introduces the number conversion. You have to say point conversion.
Well, I forgot all the questions. Let's take a look back.
Program 5: convert. c
1 # ifndef _ CONERT_H 2 # define _ CONERT_H 3 # include <stdio. h> 4 # include <math. h> 5 # endif 6 7/* 8 ** main () 9 */10 11 int conert2any (int scr, int dest_d, int pow_base) {12/* 13 ** when calling this function, the pow_base parameter must be 014 */15 int quotient, result; 16 int dest_d_base = 10; 17 quotient = scr/dest_d; 18 if (quotient! = 0) 19 result = (scr % dest_d) * pow (dest_d_base, pow_base) + conert2any (quotient, dest_d, ++ pow_base); 20 else21 result = (scr % dest_d) * pow (dest_d_base, pow_base); 22 return (result); 23}
OK, this number conversion program is implemented recursively. It is okay, but inspired by the above example, it can also be changed to a loop:
Program 6: convert_loop.c
1 do {2 result += (scr % dest_d ) * pow( dest_d_base, pow_base++ );3 } while( scr /= dest_d != 0 )
Compared with recursion, it is shorter and more efficient.
After two examples of recursion into a loop, you should find that the two examples have one thing in common: return is the last statement executed during recursion.
For this call, the final execution of return recursion is called tail recursion.
It can be found that in general, tail recursion can be changed to the corresponding loop form, which is more concise and efficient.
So when must we use recursion? According to my current experience and thinking, only program 1-print in reverse order is required. It seems that recursion is not required for others.
Now, recursion has come to an end. Let's talk about some of my feelings when I wrote program 5:
When implementing this hexadecimal conversion function, I had a poor understanding of recursion and made a ridiculous mistake: Using Recursion to achieve weighted sum, I had a hard time thinking about how to implement accumulation, after each call, the variables are destroyed. How can we accumulate them? The result is that the accumulated values are saved using static variables. So far, I will not learn recursion further. Although this can be achieved, it is not perfect. Even if the BIBO function is called, static variables still occupy space and need to be cleared before the function is called again. C language recursion should not be so troublesome. It must be something I think is worse, so I read the example repeatedly and finally realized: simply using return to return can not be accumulated. Alas, at that time, my mind was full of paste.
The full text is over. The recursion is summarized as follows:
Note:
Date: 2014-12-10