11. Function recursion and iteration

1. What is recursion?

Recursion is a method of solving problems. Recursion is when the function calls itself.
example:

int main() {
    
    
	printf("调用函数main");
	main();
	return 0;
}

The above code is just to demonstrate the form of recursion, not to solve the problem:
when the main function is called in the main function, the code eventually falls into dead recursion, calling the main function infinitely, eventually leading to stack overflow (overflow)

The output result is stuck and the error stack overflows.
Insert image description here
Insert image description here

Recursive thinking:

Convert a large and complex problem into a sub-problem that is similar to the original problem but smaller in scale to solve. Until the large problem is split, the recursion ends. That is the idea of ​​​​reducing big things into small things .


2. Restrictions on recursion

There are two necessary conditions for recursion in writing format:

1. There are restrictions on recursion. When this restriction is met, the recursion will no longer continue and will stop.
2. After each recursive call, it gets closer and closer to this limit.

Here are some examples of recursive questions to give you a feel


3. Recursive example

3.1 Find the factorial of n

计算n的阶乘(不考虑溢出),n的阶乘就是1~n的数字累积相乘。
n的阶乘的公式:n! = n ∗ (n − 1)!

1.如果n等于0,则直接返回1,因为0的阶乘定义为1
2.否则,将n与(n-1)的阶乘结果相乘,并返回这个乘积
3.直至fact(n)中的n被减至0,跳出递归

Insert image description here

//求n的阶乘
//计算n的阶乘(不考虑溢出),n的阶乘就是1~n的数字累积相乘。
int fact(int n) {
    
    
	if (n = 0) {
    
    //如果n等于0,则直接返回1,因为0的阶乘定义为1。
		return 1;
	}
	else//否则,将n与(n-1)的阶乘结果相乘,并返回这个乘积
	{
    
    
	
	//这里就是把一个大的数拆成了一个小的数乘上一个递归函数
	//直至fact(n)中的n被减至0,跳出递归
		return n * fact(n - 1);
	}
	return 0;
}

int main() {
    
    
	int n;
	scanf("%d", &n);
	printf("%d!= %d",n,fact(n));
	return 0;
}

Insert image description here

3.2 Print each digit of an integer sequentially

输⼊⼀个整数n,打印这个按照顺序打印整数的每⼀位
输⼊:1234 输出:1 2 3 4
输⼊:520  输出:5 2 0

n % 10 takes the last digit
n / 10 removes the last digit

void Print_Frist(int n) {
    
    
	if (n > 9) {
    
    
	//这里先递归再去打印最后一位
		Print_Frist(n / 10);
	}
	//打印最后一位
	printf("%d ", n % 10);
}

int main() {
    
    
	int n;
	scanf("%d", &n);
	Print_Frist(n);
	return 0;
}

Wrong idea:

void Print_Frist(int n) {
    
    
	if (n > 9) {
    
    
		//如果这里把n除以10,那么此次函数中的打印最后一位就会出问题
		n = n / 10;
		Print_Frist(n);
	}
	//打印最后一位,这里会出问题
	printf("%d ", n % 10);
}

reason:

For example, input 1234. If n = n / 10 in the if statement,
then use n as the parameter of the Print_Frist(n) function (there is indeed no problem here); however, this time the function printf("%d ", n % 10); The n in will also change accordingly. It was originally 4 and became 3 after n = n / 10.
When the function is called recursively, the function has not completely ended yet, that is, when Print_Frist(n) is called, the following printf("%d ", n % 10) has not been executed yet.
All we need is to change the parameters in the loop call function/10, and n in this function remains unchanged.


4. Recursion and iteration

Let me emphasize that in the following questions, n in int Fibonacci(int n) in the Fibonacci number function is just a parameter in the function, starting from 0; and the parameter is 0, which is the first term, and so on. (So ​​it will be +1 when printing the result) F(0) = 0 //First item F(1) = 1 //Second item

4.1 Find the nth Fibonacci number (recursion is not recommended)

斐波那契数列是一个经典的数列,在数学上以如下递归关系定义:
F(0) = 0
F(1) = 1
F(n) = F(n-1) + F(n-2)
换句话说,斐波那契数列的前两项是0和1,之后的每一项都是前两项的和。
//递归方法
int count = 0;//调用函数次数
int Fibonacci(int n) {
    
    
	if (n <= 1) {
    
    
		count++;
		return n;
	}
	else{
    
    
		count++;
		return Fibonacci(n-1) + Fibonacci(n-2);
	}
}

int main() {
    
    
	int n;
	scanf("%d", &n);
    printf("第%d斐波那契数 = %d\n", n + 1, Fibonacci(n));
	printf("共调用了函数 %d 次\n",count);
	return 0;
}

Insert image description here

Inappropriate.
This calculation can indeed get correct results, but this function has been called nearly 40 million times.
Each time a function is called in C language, a memory space needs to be allocated in the stack area to save the values ​​​​of various local variables during the function call. , this space is called the runtime stack, or function stack frame.
In the above Fibonacci number return Fibonacci(n - 1) + Fibonacci(n - 2) step, the function is recursively called again on the return value. The function has not yet ended and the space has not been released, so it is necessary to recursively open another The new memory space opens up a new stack frame space for each recursion. The stack frame space will be released layer by layer until return begins to return.

4.2 Find the nth Fibonacci number (iterative recommendation)

Iteration is a method of performing an operation or process repeatedly. In programming, iteration is typically used to process each element in a collection (such as a list, array, etc.), or to repeatedly execute a block of code until a specific condition is met. (As the name suggests, it is an update iteration, replacing the variable with another new variable.

//迭代
int count = 0;
int Fibonacci(int n) {
    
    
    if (n <= 1) {
    
    
        count++;
        return n;
    }
    int a = 0;  // 第 0 项
    int b = 1;  // 第 1 项
    int fib = 0;  // 第 n 项

    for (int i = 2; i <= n; i++) {
    
    
        fib = a + b;
        //相当于都往后走了一位,因为这三个数是连续的
        a = b;
        b = fib;
        count++;
    }
    return fib;
}

int main() {
    
    
	int n;
	scanf("%d", &n);
	printf("第%d个斐波那契数 = %d\n",n+1, Fibonacci(n));
	printf("共执行了 %d 次\n",count);
	return 0;
}

Insert image description here

The above code uses iteration efficiency which is much higher than recursion efficiency.

4.3 Summary

Although recursion is a very good idea and idea, you cannot get into recursion blindly. Any method has its own advantages and disadvantages, so specific problems should be analyzed in detail. There are many solutions to a problem, and efficiency is preferred. A tall one.

Guess you like

Origin blog.csdn.net/qq_45657848/article/details/132096859