第六讲:函数递归

在讲函数递归之前我们要知道什么是函数递归?
函数递归就是自己调用自己。这里我们要把递归这个词分开理解,递归即先递推后回归,一定要记住这个原理。

1. 递归的思想

递归的总的思想就是把一个大的问题逐步转化为一个与原问题相似,但相对于之前的问题更小的情况来求解,直到最终问题不能在被拆解为更小的问题,递推就结束了,然后在回归到原问题。所以递归的思考方式是把问题大化小的过程·。

2. 递归的限制条件

递归在书写的时候,有2个必要的条件:

递归存在的限制条件,当满足这个限制的时候,递归的递推结束。
每次递归调用之后越来越接近这个限制条件。

如果我们不给递归加上限制条件,那么将会导致程序进入死循环,程序栈溢出。

3. 递归举例

3.1 例1:求n的阶乘

计算N的阶乘(不考虑溢出),n的阶乘就是1~n的数字累积相乘。
思路分析:
假如我们求4的阶乘,那么它就是4乘以3的阶乘,那么3的阶乘不就是3乘以2的阶乘么?

4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1

上面的的显示我们分析出n的阶乘就是n * (n-1)!(n-1)!的阶乘就是(n-1) * (n-2)!。直到n为1或者0时,阶乘结束。
我们用代码演示下:

#include <stdio.h>
int func(int n)
{
	if (n == 1)
	{
		return 1;
	}
	else
	{
		return n * func(n - 1);
	}
}

我们测试下:

#include <stdio.h>
int func(int n)
{
	if (n == 1)
	{
		return 1;
	}
	else
	{
		return n * func(n - 1);
	}

}

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

运行结果:
在这里插入图片描述

3.1.2 画图演示

在这里插入图片描述

3.2 例2:顺序打印一个整数的每一位

输入一个整数m,顺序打印这个整数的每一位。
比如:

输入:1234 输出:1 2 3 4
输入:520 输出:5 2 0

分析:
我们知道当输入一个十进制整数时,如果要得到这个数的个位数,那么我们就用这个数求余10。如果要得到十位数的数,就把这个数字除以10,然后再求余,即得到十位数的数字了。但是这种情况下输出的是 反序的。
我们用递归来实现的话,就是把这个数值除以10得到的数字传递给函数,直到最后传递进去的数值小于9时回归,执行下面的语句。为什么是大于9,因为当商为小于9的数值,那么就是到了最后一位数了。

#include <stdio.h>

void func(int n)
{
	if (n > 9)
	{
		func(n / 10);
	}

	printf("%d ", n%10);
}

int main()
{
	int x = 0;
	scanf("%d", &x);
	func(x);
	return 0;
}

输出结果:
在这里插入图片描述

3.2.1 画图演示

在这里插入图片描述

4. 递归与迭代

我们通常说的迭代,通常情况下指的就是循环,递归虽然是一种很好的编程技巧,但是也有被误用的情况,比如例1,知道递归的原理我们很容易就能写出来递归形式的代码,当然我们用循环也能实现,但是递归相对于循环,代码更简洁一些。
这里我们要注意,如果递归使用不当,将会使程序进入大量的计算中,此时使用迭代会是一种很好的解决办法。比如斐波那契数列的实现,虽然用递归可以实现,但是计算机要经过大量的计算才能得出数值,而迭代的方式相比较起来会更简单。
递归实现斐波那契数列

#include <stdio.h>
int feb(int x)
{
	if (x <= 2)
	{
		return 1;
	}
	else
	{
		return feb(x - 1) + feb(x - 2);
	}
}

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

此时我们用递归实现斐波那契数列,如果求小的值还可以,但是过大的值将会让程序进入大量计算,很大可能会导致栈溢出。
而我们用迭代的方式,就没有那么大的计算量。

#include <stdio.h>
int main()
{
	int a = 1;
	int b = 1;
	int c = 1;
	int num = 0;
	scanf("%d", &num);
	if (num <= 2)
	{
		printf("%d", c);
	}
	else
	{
		int i = 0;
		for (i = 2;i < num;i++)
		{
			c = a + b;
			a = b;
			b = c;

		}
		printf("%d", c);
	}
	return 0;
}

本博客只为学习使用,如有错误请大佬指出,感谢大家支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值