The beauty of data structures and algorithms (recursion)

1. What is recursion?

To put it bluntly, it is to call yourself. You should have seen the video of the box and the box. The
commonly used ones are dfs and binary tree (linked list form) traversal.

Satisfy the recursion condition:

  1. The solution of a problem can be decomposed into the solutions of several sub-problems. This problem is the same as the sub-problems after decomposing, except that the data scale is different, the solution idea is exactly the same (more and more simple)
  2. There is a recursive termination condition (in other words an exit)

template:

void recursion(参数0) {
    
    
    if (终止条件) {
    
    
        return;
    }
    
    recursion(参数1);
}

2. Why use recursion? Advantages and disadvantages of recursion?

  • 1. Advantages: The code is expressive and concise.
  • 2. Disadvantages: high space complexity, risk of stack overflow, repeated calculation, too many function calls will take more time.

3. What kind of problems can be solved by recursion?

1, factorial

//递归法就n的阶乘
public class MainClass {
    
    
    public static void main(String args[]) {
    
    
    for (int counter = 0; counter <= 10; counter++){
    
    
        System.out.printf("%d! = %d\n", counter,
        factorial(counter));
    }
    }
    public static long factorial(long number) {
    
    
        if (number <= 1)
            return 1;
        else
            return number * factorial(number - 1);
    }
}

2. Fibonacci sequence

Let's look at another classic recursion problem, which is the Fibonacci sequence. The first few items of the sequence are as follows

[1,1,2,3,5,8,13……]

The two conditions for recursion, one is the termination condition, we found. The other is to call ourselves, we know that the current value of the Fibonacci sequence is the sum of the previous two values, that is

Fibonacci (n) = Fibonacci (n - 1) + Fibonacci (n - 2)

//1,1,2,3,5,8,13……
public int fibonacci(int n) {
    
    
    if (n == 1 || n == 2)
        return 1;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

3. Tower of Hanoi

I'm sure everyone has seen this
insert image description here

The principle of the Tower of Hanoi is briefly mentioned here, that is, there are three pillars A, B, and C. The disks on the pillar A are arranged from top to bottom in order from small to large. Move all the disks on the A pillar to the C pillar by the B pillar, and the process of moving is always the small disk on the top and the big one on the bottom. We still solve this problem recursively.

#include <bits/stdc++.h>
 
using namespace std;
 
void Move(int n, char A, char B, char C)
{
    
    
	if (n == 1)
	{
    
    
		//圆盘只有一个时,只需将其从A塔移到C塔
		cout << "把" << n << " 从" << A << " 移动到" << C << endl;
	}
	else
	{
    
    
		Move(n - 1, A, C, B);//递归,把A塔上编号1~n-1的圆盘移到B上,以C为辅助塔
		cout << "把" << n << " 从" << A << " 移动到" << C << endl;//把A塔上编号为n的圆盘移到C上
		Move(n - 1, B, A, C);//递归,把B塔上编号1~n-1的圆盘移到C上,以A为辅助塔
	}
}
 
void Hanoi(int n)
{
    
    
	if (n <= 0)
		return;
	Move(n, 'A', 'B', 'C');
}
 
int main()
{
    
    
	Hanoi(3);
	return 0;
}

Fourth, how to achieve recursion?

Let's talk about how to implement it here. I believe everyone has read the above recursive code and understands it almost.

In general:

Write the recursion formula to find the termination condition

Five, recursive common problems and solutions

  • Be wary of stack overflows: You can declare a global variable to control the depth of recursion, thus avoiding stack overflows.
    Workaround:
    This problem can be solved by limiting the maximum depth of recursive calls in the code
  • Be wary of double-computing: save already solved values ​​in a data structure to avoid double-computing.
    Solution:
    In order to avoid double calculation, we can save the solved f(k) through a data structure (such as a hash table). When the recursive call reaches f(k), first see if it has been solved. If it is, return the value directly from the hash table, without repeating the calculation, so that the problem just mentioned can be avoided.

6. How to rewrite recursive code to non-recursive code?

This is very simple to change the recursive code into a loop (that is, iteration), how to write
it or use Fibonacci

Recursive code:

int fib(int n){
    
      
         if(n>1) return fib(n-1) + fib(n-2);  
         else return n; // n = 0, 1时给出recursion终止条件  
    }  

Iterate:

int fib(int n){
    
      
    int i, temp0, temp1, temp2;        
    if(n<=1) return n;  
    temp1 = 0;  
    temp2 = 1;  
    for(i = 2; i <= n; i++){
    
      
        temp0 = temp1 + temp2;  
        temp2 = temp1;  
        temp1 = temp0;  
    }  
    return temp0;  
} 

Guess you like

Origin blog.csdn.net/qq_54729417/article/details/122884762