C语言-函数递归

一、函数递归

1.递归是什么

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

#include <stdio.h>
int main()
{
    printf(" hehe\n ");
	main();//这就是函数递归
	return 0;
}

2.递归的思想

把一个大型复杂的问题层层转化为与原问题相似,但规模比较小的问题求解;直到直到子问题不能再拆分,递归结束

3.书写递归的条件

• 书写递归条件,当满⾜这个限制条件的时候,递归便不再继续
• 每次递归调⽤之后越来越接近这个限制条件

二、函数递归举例

1.求n的阶乘

(1)题目

题⽬:计算n的阶乘(不考虑溢出),n的 阶乘就是1~n的数字累积相乘

(2)分析

•n的阶乘的公式: n! = n ∗ (n − 1)!
•n的阶乘和n-1的阶乘是相似的问题,但是规模要少了n

 n!= n*(n-1)*...*2*1
 (n-1)= (n-2)*(n-3)*...*2*1
 5= 5*4*3*2*1
 4= 4*3*2*1
 3= 3*2*1
 2= 2*1
 1= 1

•有⼀种有特殊情况是:当 n==0 的时候,n的阶乘是1

所以我们可以得出这个方程
在这里插入图片描述

(3)解法

递归解法

#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 r = Fact(n);
	printf("%d",r);
	return 0;
}

常规解法

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

2.顺序打印每个整形的每一位

(1)题目

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

(2)分析

n如果大于9,就需要拆分。
例如:1234%10得到4,/10得到123。以此类推,不断地进行%10 /10的操作,就可以得到1234的每一位。但是有一个问题得到的数字是倒着打印的。我们可以发现其实⼀个数字的最低位是最容易得到的,通过%10就能得到。

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)

(3)解法

void Print(int n)
{
   if(n>9)
   {
     Print(n/10);
   }
   Print("%d", n%10);
}

int mian()
{
   int n = 0;
   scanf("%d", &n);
   Printf(n);
   return 0;
}

三、递归与迭代

在C语⾔中每⼀次函数调⽤,都需要为本次函数调⽤在内存的栈区,申请⼀块内存空间来保存函数调⽤期间的各种局部变量的值,这块空间被称为运⾏时堆栈,或者函数栈帧。函数不返回,函数对应的栈帧空间就⼀直占⽤,所以如果函数调⽤中存在递归调⽤的话,每⼀次递归函数调⽤都会开辟属于⾃⼰的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间。所以如果采⽤函数递归的⽅式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出(stack overflow)的问题。

所以如果不想使用递归,我们就得想别的办法,通常情况下我们会使用迭代的方式**(迭代通常就是循环)**

例如例题求n的阶乘
我们的常规解法便是迭代解法

#include <stdio.h>
int main()
{
	int n = 0;
	int i = 0;
	int sum = 1;
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		sum *= i;
	}
	printf("%d", sum);
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值