Recursion in C language

Source: Internet
Author: User

Ideas

It describes the thinking process from problem to problem variation:

Overview

In this paper, the recursive analysis is carried out with the conversion of the numeral. It is mainly to analyze recursive process from multi-angle and discuss recursive characteristics and usage.

Introduction

At the time of completing a program, suddenly want to implement any number of conversions to each other, and then pondering, at least the following parameters are involved:

    1. SOURCE Number: SCR
    2. Target system: Dest_d
      The general idea of implementation:
      SCR--Digital decomposition--weighted sum--dest
      It is obvious that this process is first-order decomposition, and then the inverse of the sum, so I associate with recursion.
Recursive 1. Meaning of recursion
    1. 递归就是递归函数。递归函数是直接或间接调用自身的函数。

As an example:

Program 1:BTOA.C
1         /*2 * * Accepts an integer value (unsigned), converts it to a character and prints it, leading 0 is deleted. 3         */4#include <stdio.h>5     voidBinary_to_ascii (unsignedintvalue) {6Unsignedintquotient;7Quotient = value/Ten;8         if(Quotient! =0)9 binary_tc_ascii (quotient);TenPutchar (value%Ten+'0' ); One}


另外递归还有所谓“三个条件”,“两个阶段”。我就不说了。实际应用时一般都很自然的满足条件。

2. 递归过程分析
    • 中断角度
看例:
有5人从左至右坐,右边人的年龄比相邻左边人大2岁,最左边的那个人10岁。问最右边人年龄。
    1. 程序2: age.c
    2. 1#include <stdio.h>2AgeintN) {3     intC;4     if(n = =1 )5c =Ten;6     Else7c = Age (n1) +2;8     return(c);9 }Ten  One intMain () { Aprintf"%d\n\n", Age (5 ) ); -     return 0; -}

An expression:

The recursive and push-back process:
Main () Age () Age () Age () ()
n = 5 N = 4 N = 3 N = 2 N = 1
Recursion: Age (5)---> c = Age (4) + 2---> c = Age (3) + 2---> c = Age (2) + 2---> c = Age (1) + 2---> c = 10
Back: Output Age (5) Age (5) = B <---age (4) = 2 <---age (3) = + <---age () = <---return (c)

What is the connection to the interruption? It does not seem obvious at the moment, but at first I was thinking of the interruption in the microcomputer principle: starting with age (5), then calling age (4), that is, to an interrupt, protecting the scene first, then recursively until the n=1, the end of the interruption, and then the return of the layer, that is, the process of resuming the scene.

  • Nesting invocation angle:
    Nested Call Graphs:

    Understand this figure, the above fun_a () and Fun_b () all into the same fun (), is equivalent to the recursive function of the call process itself.
    In addition, it seems that this picture is more likely to see the "interruption process".

  • Stack angle
    If both the interrupts and nesting angles are understood, the stack angle is sublimated.
    Also use Program 1 as an example to analyze:
    The function of program 1 has two variables: parameter value and local variable quotient. Some of the graphs below show the status of the stack, which is currently accessible at the top of the stack. All other called variables are shaded in shades of gray, indicating that they cannot be accessed by the currently executing function.
    Suppose we call a recursive function with a value of 4267. When the function starts executing, the contents of the stack are as shown.

    After performing the division operation, the contents of the stack are as follows:

    Next, the If statement determines that the value of quotient is nonzero, so a recursive call is performed on the function. When the function is called the second time, the contents of the stack are as follows:

    A batch of new variables is created on the stack, hiding the previous variables, which cannot be accessed unless the current recursive call returns. After the division operation is performed again, the contents of the stack are as follows:

    The value of quotient is now 42 and is still nonzero, so you need to continue with recursive calls and create a batch of variables. After performing the division operation of this call, the contents of the stack are as follows:

    At this point, the value of quotient is nonzero, and recursive calls still need to be performed. After performing the division operation, the contents of the stack are as follows:

    The statements executed so far are only division operations and test the value of quotient, not the recursive call statement itself. Because recursive calls cause these statements to execute repeatedly, it works like a loop: when the value of quotient is nonzero, it restarts the loop with its value as the initial value. However, recursive calls will hold some information (this is different from the loop), which is the value of the variable stored in the stack. This information will soon become very important.
    Now that the value of quotient becomes 0, the recursive function no longer calls itself, but instead begins printing the output. The function then returns and begins destroying the value of the variable on the stack.
    Each call to Putchar gets the last number of the variable value, by modulo 10 for value, and the result is an integer between 0~9. Add it to the character constant ' 0 ' and the result is the ASCII character that corresponds to the number, and then print out the character.

    The function then returns, and its variables are destroyed from the stack. Then, the previous invocation of the recursive function resumes execution, and it uses its own variables, which are now at the top of the stack. Because its value is 42, the number printed after calling Putchar is 2.

    The call to the recursive function is also returned, and its variables are destroyed, at the top of the stack is the variable that the recursive function was called before. The recursive call proceeds from this position, and the number printed this time is 6. Before this call returns, the contents of the stack are as follows:

    Now we have expanded the entire recursive process and returned to the original invocation of the function. This call prints out the number 7, which is the remainder of its value parameter except 10.

    The recursive function then returns to the location where other functions call it.
    If you line up the printed characters one by one and appear on the printer or screen, you will see the correct value of 4267.

    3. Application of recursion

    The recursive process is analyzed from different angles. The international application does not require you to understand each recursive internal process, it is important to use the right.
    The following are some examples of inappropriate application recursion:
    The computational factorial and Fibonacci sequences are used in many textbooks to illustrate recursion, whereas recursion in the former does not provide any superiority, and the efficiency of recursion in the latter is very low.
    Take a look at the extreme Fibonacci number solver:
    An expression:
      
    This recursive form of definition is apt to induce people to use recursive forms to solve problems:

    Program 3:FIB_REC.C
    1 /*2 * * The value of the nth Fibonacci sequence is computed using a recursive method. 3 */4 5 intFibonacciintN) {6     if(N <=2 )7         return 1;8     returnFibonacci (N-1) + Fibonacci (N-2 );9}

    Here's a trap: it uses recursive steps to calculate fibonacci ( Span class= "PLN" > n - 1 ) Fibonacci ( n Span class= "pun" >- 2 ). However, in the calculation Fibonacci ( n - 1 Fibonacci ( n - 2 ). How big is this extra cost? fibonacci ( 10 fibonacci ( 3 The value of 21 times. But in the recursive calculation fibonacci ( 30 fibonacci ( 3 The value of 317811 times, of course, this 317811
      1.   想得更极端一些,假如你在程序中递归时不是两次而是3次,4次,更多次的调用自身,那我想可能会让程序崩溃吧。
      2.   现在让我们尝试用循环代替递归:
      3. 程序4:fib_iter.c
1 intFibonacciintN) {2     intresult;3     intPrevious_result;4     intNext_older_result;5result = Previous_result =1;6      while(N >2 ) {7N-=1;8Next_older_result =Previous_result;9Previous_result =result;Tenresult = Previous_result +Next_older_result; One     } A     returnresult; -}

    1.   OK,说到这了,本文引子是数制转换,总得说点数制转换点题是吧。
Well, forget all the questions, go back to the intro and look at it.
Program 5:CONVERT.C
1 #ifndef _conert_h2     #define_conert_h3#include <stdio.h>4#include <math.h>5 #endif6 7 /*8 **main ()9 */Ten  One intConert2any (intScrintDest_d,intpow_base) { A /* - * * Parameter pow_base must be 0 when calling this function - */ the     intquotient, result; -     intDest_d_base =Ten; -quotient = SCR/Dest_d; -     if(Quotient! =0 ) +result = (scr% dest_d) * POW (dest_d_base, pow_base) + conert2any (quotient, dest_d, + +)pow_base); -     Else +result = (scr% dest_d) *Pow (dest_d_base, pow_base); A     return(result); at}

OK, this conversion program is implemented recursively with no problem, but it can also be changed to a loop by the above example:

Program 6:CONVERT_LOOP.C
1  Do {2     result + = (scr% dest_d) * POW (dest_d_base, pow_base++ ); 3  while 0 )

It is more concise and more efficient than recursion.

After two recursive changes to the loop example, you should find that the two examples have one thing in common: the last statement executed when the recursive call is return.
For this kind of invocation, the last execution is the return recursion, there is a special salutation: tail recursion.
It can be found that in general the tail recursion can be changed to the corresponding loop form, and more concise and efficient.
When do we have to use recursion? According to my current experience and thinking, only the procedural order of the reverse print is necessary, others do not seem to have to use recursion.
Well, to this recursion also came to an episode, to talk about my writing program 5 o'clock some of the feelings:
When implementing this conversion function, the understanding of recursion is not deep enough to make a mistake that now seems ridiculous: it is to use recursive implementation of weighted summation, I have also puzzled how to achieve the cumulative, each call after the end of the variables are destroyed, how to accumulate it? The result is a static variable that holds the accumulated value. If that's the end, I won't study recursion any further. Because I think, although this can be achieved, but not perfect, even if the blue waves function call, static variables still occupy space, and again before the call to clear zero. C language recursion should not be so troublesome, must be where I think bad, so I repeat the example of reading, finally woke up: directly return with return can not be realized. Alas, the brain was really filled with paste.

At the end of the article, summarize the recursion:

    1. Recursion is a nested invocation of a function on itself.
    2. In general, the tail recursion is not necessary, it is better to use the loop.
    3. Recursive analysis repeats the process hierarchy, so it is best to use recursive analysis first, and then switch to the loop to achieve.

Description

    1. Procedure 1,3,4 from "C and pointers" 7.5
    2. Program 2 from the school's textbook "C Language Programming" 7.4
    3. "Stack angle" quoted from "C and pointers" 7.5

Date:2014-12-10



From for notes (Wiz)



List of attachments
    • E1.png
    • E2.png
    • E3.png
    • E4.png
    • E5.png
    • E6.png
    • T1.png
    • T2.png
    • T3.png
    • T4.png

Recursion in C language

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.