六. C语言函数递归

前言:函数递归是一个比较抽象的部分,但在C语言中用的也比较多,今天我来分享一下关于函数递归的知识.

1. 递归的含义

 很多同志看到递归这个词会有点懵

其实,递归是一种与嵌套类似的解决问题的方法

在C语言中

递归就是 函数自己调用自己

即递推+回归

在此,我给出一个最简单的C语言递归

#include <stdio.h>

int main()
{
	printf("love\n");
	main();      //调用main函数
	return 0;
}

上面代码在打印完 "love" 后,再次调用main函数,接着又打印 "love",进入无限循环

我用一种方式来更加清楚了解一下 函数递归

当然,从实际意义考虑的话,上面代码是无意义

2.递归的意义

递归,可以让一个复杂的问题,拆分成一小块一小块,直到小问题不再能拆分

接下来,请大家慢慢体会

3.递归的限制条件

   递归书写的时候需要写限制条件

— 如果递归时满足这个限制条件递归不再进行

随着递归的进行将越来越接近这个限制条件

4.递归举例

   求n的阶乘

  n的阶乘:1*2*3*...(n-1)*n

      例如:

                  假设n是4,那么n的阶乘就是 4*3*2*1

                  即    4!=4*3*2*1

   加入递归思想,这道题将变成一个一个规模较小的式子(n>1)

  

直到 n 等于 1或时,不再拆解

接下来,我们实际操作一下

#include <stdio.h>

int Fact(int n)
{
	if (n <= 0)
		return 1;  
	else
		return n * Fact(n - 1);  //在这里开始递归
}

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

运行结果

我们用图画推导一遍

5.递归的弊端

递归是一个很好的解决问题的方法,但是像其他方法一样,有很多时候我们容易去误用它,这时候我们就得用循环来解决了

例如:

     求第n个斐波那契数

这是一个极端的例子,能充分反映递归的弊端

   斐波那契数列:1  1  2  3  5  8  13  ...  

   第n个斐波那契数:F(n)=  F(n-2)+F(n-1)      →  n>2  

                                  F(n)= 1                           →   n<=2

递归斐波那契

假如我们把斐波那契写成递归的形式,如下:

int F(int n)
{
	if (n <= 2)
		return 1;
	else
		return F(n - 1) + F(n - 2);
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int r = F(n);
	printf("%d\n", r);
	return 0;
}

也许当你求第小于50位的斐波那契数的时候,发现没问题,而且很对

但是当你输入第50位或50位往后的时候,发现程序加载不出来结果

这是为什么呢?

我们不妨画个图

我们可以看到,随着递归的不断深入,有许多重复的计算,而且递归次数指数增加,导致程序计算量大,效率低

循环斐波那契

而当我们用循环解决第n个斐波那契数时,我们会发现,计算量少了很多很多

我们尝试写一下循环

斐波那契数前两位数为1,1

我们可以实现(n>=3)

仔细思考,我们会发现,计算第n个斐波那契数只需要计算n-2

int F(int n)
{
	int a = 1;
	int b = 1;
	int c = 1;  //n是1,2时,不会进入循环,直接打印1
	while (n >= 3)
	{
		c = a + b;    
		a = b;
		b = c;
		n--;
	}
	return c;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int r = F(n);
	printf("%d\n", r);
	return 0;
}

当我们输入50时,我们发现计算速度很快,但是是个负数?

这是因为,整型变量是有范围的,超出范围会随机报数(就像许多类型变量都是有范围的)

但是你会发现,计算很快很快,甚至如果你输入50000,速度也是很快(虽然结果依然是错的)

6.递推的选择

      在未来解决问题时,如果使用递归非常容易,并且写出的代码也没问题,那就使用递归

     但如果使用递归有明显缺陷,那就不能使用递归,需要考虑其它方法:迭代(循环是迭代的一种)

    

总结:函数递归固然能很好的解决问题,但是问题千千万,总有一些刁钻的问题不能使用递归,还容易让我们陷进去. 

          所以,不仅仅是这一块,整个C语言包括其它编程语言,在解决实际问题时,都不能单一的只思考一个方法,而是运用它们各自优势,互相配合着解决问题.

作者留言:本人是初学者,制作不易,如有错误和不恰当的地方,欢迎指出和分享建议

                                                                             制作时间:2023.12.8

            

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值