[Data structure learning record 7]-stack and recursion (in fact, more analysis and recursion)

1. Recursion

1. Concept

What is recursion is the one we learned in high school mathematics, recursion. Of course, if a recurrence formula is expressed as a function, then we can call this function 递归函数. 递归函数It is a function that calls itself directly or through a series of statements, called a recursive function.

For example, our factorial function:
F act (n) = {1, n = 0 n ⋅ F act (n − 1), n> 0 Fact(n)=\left\{ \begin{aligned} 1,n=0 \\ n\cdot Fact(n-1),n>0\\ \end{aligned} \right.Fact(n)={ 1,n=0nFact(n1),n>0
Or the familiar Fibonacci sequence:
F ib (n) = {0, n = 0 1, n = 1 F ib (n − 1) ⋅ F ib (n − 2), n> 1 Fib( n)=\left\{ \begin{aligned} 0,n=0\\ 1,n=1\\ Fib(n-1)\cdot Fib(n-2),n>1\\ \end{aligned } \right.Fib(n)=0,n=01,n=1Fib(n1)Fib(n2),n>1

2. Realize

We may think of the constant term, is called 递归边界, such as factorial f(n)=1,n=0Fibonacci number or the Fibonacci sequence f(n)=0,n=0, f(n)=1,n=1.

Then we write a recursive code that implements the Fibonacci sequence:

int Fib(int n)
{
    
    
    if (n == 0) return 0;
    else if (n == 1) return 1;
    else
    {
    
    
        return Fib(n-1) + Fib(n-2);
    }
}

int main()
{
    
    
    printf("%d", Fib(10));
    return 0;
}

As long as we can write a recursive function expression, we can write its recursive function. In my opinion:The recursive boundary is the most important. If the recursion boundary is not handled properly, then the recursion may continue forever, and then burst into death.

3. Harder recursive analysis-Tower of Hanoi

Insert picture description here

The rules of the game in the Tower of Hanoi are: move the plate in A to plate C, and the large plate cannot be placed on the small plate.

For this we try a few more times:

  1. n=1

    1st Set 1 A---->C

  2. n=2

    The 1st Set 1 A---->B

    2nd Set 2 A---->C

    3rd Set 1 B---->C

  3. n=3

    1st Set 1 A---->C

    The second round No. 2 A---->B

    3rd Set 1 C---->B

    4th Set 3 A---->C

    The 5th round No. 1 B---->A

    6th Set 2 B---->C

    7th Disk 1 A---->C

If we use the holistic approach, if we move a pile of plates from A to C, then we can regard the plates on the A pillar as two wholes, the bottom plate and all the plates on it. Then our process is:

  1. All the plates above from A to B
  2. The bottom plate goes from A to C
  3. All the plates above from B to C

So how do we move the top plate to B and C? Think of this part of the plate as two parts, the bottom plate and all the plates on the top.

If we move to B, then C is our auxiliary tower (because the game moves from A to C, so B is an auxiliary tower), so we will perform the "A to B Tower of Hanoi operation" on the upper part.

Conversely, if you move from B to C, A is the auxiliary tower, so what we are performing is "B to C's welding notch operation"

Start the doll. Until the end we only have one plate, so obviously, it performs "A to C Tower of Hanoi operation" and only has one plate, then move it to C.

Then our recursive expression comes out:

Recursion boundary: n=1时 把1号盘子 A→C

Recursive content: ① 把n-1号盘子 A→B把n号盘子 A→C把n-1号盘子 B→C

Okay, the code is implemented:

void hano(int n, char a, char b, char c)    // hano(n=有几个碟子,a=主塔,b=辅助塔,c=目标塔) 
{
    
    
    if (n == 1) printf("No.%d  %c -> %c\n", 1, a, c);
    else
    {
    
    
        hano(n - 1, a, c, b);   // 这里是A to B的操作,C是辅助塔
        printf("No.%d  %c -> %c\n", n, a, c);
        hano(n - 1, b, a, c); // 这里是B to C的操作,A是辅助塔
    }
    
}

int main()
{
    
    
    hano(3, 'A', 'B', 'C'); // 这里是A to C的操作
    return 0;
}

2. The relationship between stack and recursion

In high-level languages, if you need to call (this is the verb) function, then 调用(名词)函数, and 被调用函数links to information exchange between needs through internal stack.

Before running the called function, the system will complete three things:

  1. Pass all the actual parameters, return address and other information to the called function to save.
  2. Allocate storage area for the local variables of the called function
  3. Transfer control to the entry of the called function.

Then before the called function returns to the calling function, we have to complete three things:

  1. Save the calculation result of the called function
  2. Release the data area of ​​the called function
  3. Transfer control to the calling function according to the return address saved by the called function.

Suppose we make nested calls like recursively, then the function called first must return last, so inside the compiler, these relationships and information are saved for us through the stack.

So the information transfer between our recursion needs to use the stack. Fortunately, the compiler will manage 递归工作栈it for us, so we only need to consider the recursion boundary and the content of the recursion!

Guess you like

Origin blog.csdn.net/u011017694/article/details/109428873