函数递归。。。

函数递归是什么

递归是一种解决问题的方法,在C语言中就是函数自己调用自己。利用函数递归可以解决一些简单但是很繁琐的问题,比如经典的求斐波那契数列和青蛙跳台阶问题,在本次函数递归的学习中,我们会对这个问题进行详细的解释。

递归的思想
把一个大型复杂的问题,转化为一个与原问题相似,但规模小的子问题来求解,简单来说就是大事化小小事化了的思想。
递归:这个词就是递推和回归的意思

为了帮助更好的理解,我们下面来看一个最简单的递归

void print()
{
	printf("hehe");
	print();
}

int main()
{
	print();
	return 0;
}

看一下这个代码,这就是一个打印hehe的递归,但是这个代码不会无限循环,它会报错,原因就是因为这个递归函数没有终止条件,递归会无限制地执行下去,直到程序耗尽系统栈空间或导致系统崩溃。这种情况被称为无限递归,是一种常见的编程错误,容易导致程序崩溃。

所以,函数递归要满足下面的要求

递归程序必须有一个结束条件,并且每一次递归都更加的接近这个条件。

int i = 10;

void print()
{
	printf("hehe\n");
	i--;
	if(i>0)
	print();
}

int main()
{
	print();
	return 0;
}

看,上面是我们改之后的正确代码,这样设置了递归终止条件,每一次调用函数都更加的接近这个终止条件。

斐波那契数列

斐波那契数列:前两个数相加得到第三个数,前两位数组是1
1 1 2 3 5 8 13……
就是这样一个数列,假如我们现在要求该数列中第n个数是多少,要知道第n个数的大小,我们就要先知道n-1和n-2的大小,把这两个相加得到n的大小。但是要想知道n-1是多少,就要知道(n-1)-1和(n-1)-2的大小。分析这个思路,我们这里可以把这个复杂的程序分解成一个个的子问题来求解
来,我们看看如何用递归的方法实现这个代码

int Fib(int n)
{
	if (n < 3)
		return 1;
	else
		return Fib(n - 1) + Fib(n - 2);
}

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

这是一个比较经典的函数递归代码,我们来理解一下这段代码,
令n=4,进入Fib函数,执行else中的return语句,

ret=Fib(3)+Fib(2)
Fib(3)又进入else中的return语句
Fib(2)返回if中的return语句,返回1

Fib(3)=Fib(2)+Fib(1)
Fib(2)和Fib(1)都返回1
即Fib(4)=Fib(3)+Fib(2)=Fib(2)+Fib(1)+Fib(1)
返回的ret=3

在求斐波那契数是,递归只是一种实现方法,如果你在程序中输入50来求第50位斐波那契数,该程序一时半会得不到答案,原因是什么呢

我们来更改一下这个代码,计算一下n=3时,函数调用了几次

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

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

在这里插入图片描述

使用count来计算一下,我们发现计算斐波那契数列的第40个数,n=3函数调用了4千万次,可见,递归的方法求斐波那契数列效率是非常低的,它在不停的重复计算,当n=50时,他的计算量是非常大的
在这里插入图片描述
看,仅仅是多计算了一位,n=3调用就增加了两千万次。

从这里我们可以得出,不要过于依赖递归这种方法,它只是在某些情况下受用
对于求斐波那契数列,显然递归的方法是不合适的,我们可以使用迭代的方法,这样大大提高程序的效率

int Fib(int n)
{
	long long a = 1;
	long long b = 1;
	long long c = 1;
	while (n >= 3)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}

看这段就是迭代的代码实现,大大提高了效率。

了解了函数递归,我们来看一个经典的递归题

青蛙跳台阶问题
一只青蛙跳台阶,一次只能跳一个或两个台阶,问跳n阶台阶共有多少中跳法。

有n阶台阶,第一次跳,剩下的台阶可能是n-1或者n-2,、

若是n-1,则第二次剩n-2或者n-3阶台阶
若是n-2,则第二次剩n-3或者n-4阶台阶
……
以此类推

在这里插入图片描述

看上面的图来帮助理解,结果是0或1则返回1就表示这是1中跳台阶的方法。

想必你也已经看出来了,这与斐波那契数列差不多,所以我们只需要拿来斐波那契的代码过来稍作调整就可以了

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

int main()
{
	int n = 0;
	scanf("%d", &n);
	long long ret = Fib(n);
	printf("%ld\n", ret);
	return 0;
}

这里再提一下汉诺塔,这也是一个经典的递归题,感兴趣的可以去了解一下,增加一下对递归的理解

感谢观看,有错误请指出

在这里插入图片描述

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~nilv

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值