函数递归详解

       本章讲述的是有关函数递归的内容,虽然内容很少,但是对于初学者来说递归的思想并不简单,因此希望本章内容对你有所帮助。

1.什么是递归

       在学习之前,我们要先了解什么是递归,递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰,什么意思呢,我们来看下面这段代码。

#include <stdio.h>
int main()
{
    printf("hehe\n");
    main();//main函数中⼜调⽤了main函数
    return 0;
}
     上述就是⼀个简单的递归程序,只不过上⾯的递归只是为了演⽰递归的基本形式,不是为了解决问题,代码最终也会陷⼊死递归,我们在这里只需要直到,递归就是调用自己的过程。

1.递归的思想

       了解了递归,之后我们就要明白递归的思想是什么,它有什么用,其实递归的思想就是把⼤事化⼩的过程。

       递归中的递就是递推的意思,归就是回归的意思,在这里大家可能会感觉有点抽象,没关系,大家只要有个印象就行,之后我会带大家一步一步去了解。

2.递归的限制条件

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

递归存在限制条件,当满⾜这个限制条件的时候,递归便不再继续。

每次递归调⽤之后越来越接近这个限制条件。

在下⾯的例⼦中,我们来逐步体会这2个限制。

2.递归举例

  1.举例1:求n的阶乘

我们首先用循环来实现这个题目

#include<stdio.h>
int main()
{
	int n = 0;
	int ret = 1;
	scanf("%d", &n);
	for (int i = n; i >0; i--)
	{
		ret *= i;
	}
	printf("%d", ret);
	return 0;
}

我们可以看到循环实现很简单,那么用递归怎么去做呢?

我们知道n的阶乘的公式: n =   n ∗ ( n − 1)!
举例:
5!   = 5*4*3*2*1
5!   = 5*4!
4!= 4*3!
3!= 3*2!
2!= 2*1
我们发现这就是一个逐步递推的过程,同时我们也把一个大问题转换成了一个个小问题。
我们知道,递归是有限制条件的,这个题目的限制条件就是当n==0时, n的阶乘是1,我们直到递归是在函数中进行的,因此我们创建一个Fact(n)函数来实现阶乘的实现。
我们代码实现一下
#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\n", ret);
	return 0;
}

我们画图推演一下

此时就是递推的过程,那回归是怎么回的呢?

蓝色代表就是回归的过程

2.举例2:顺序打印⼀个整数的每⼀位

输⼊⼀个整数m,打印这个按照顺序打印整数的每⼀位。
⽐如:
输⼊:1234 输出:1 2 3 4
输⼊:520 输出:5 2 0
如果n是⼀位数,n的每⼀位就是n⾃⼰,n是超过1位数的话,就得拆分每⼀位 1234%10就能得到4,然后1234/10得到123,这就相当于去掉了4然后继续对123%10,就得到了3,再除10去掉3,以此类推不断的 %10 和 /10 操作,直到1234的每⼀位都得到。
如果我们用循环来做的话,会比较麻烦,由于%10得到的是最低位,而我们要顺序打印,就更麻烦了,不过我们知道递归的回归是从尾回到头,就可以避免这个问题。
我们假设想写⼀个函数Print来打印n的每⼀位,如下表⽰:
Print(n)
如果 n 1234 ,那表⽰为
Print( 1234 ) // 打印 1234 的每⼀位
其中 1234 中的 4 可以通过 % 10 得到,那么
Print( 1234 ) 就可以拆分为两步:
1. Print( 1234 / 10 ) // 打印 123 的每⼀位
2. printf ( 1234 % 10 ) // 打印 4
完成上述 2 步,那就完成了 1234 每⼀位的打印
那么 Print( 123 ) ⼜可以拆分为 Print( 123 / 10 ) + printf ( 123 % 10 )
以此类推下去,就有
Print( 1234 )
==>Print( 123 ) + printf ( 4 )
==>Print( 12 ) + printf ( 3 )
==>Print( 1 ) + printf ( 2 )
==> printf ( 1 )
void Print(int n)
{
    if(n>9)
   {
      Print(n/10);
   }
   printf("%d ", n%10);
}
int main()
{
   int m = 0;
   scanf("%d", &m);
   Print(m);
   return 0;
}

同样我们画图看一下

3.结语

        递归的内容很少,但是它理解起来却很难,不过它却很能锻炼编程的思维逻辑能力,我们在写代码时,如果代码能用循环实现,尽量不去用递归,因为递归的开销太大,那我们为什么要学习呢,其实,到后期有些问题必须要递归去解决,因此递归虽然理解难,又比不上循环,但是我们还是有学习的必要,最后永远都不要放弃,坚持才是胜利!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值