c语言函数递归与迭代

本文介绍了C语言中递归的概念,如何避免死循环和栈溢出,以及递归在计算阶乘和斐波那契数时的局限性。通过递归和迭代的对比,强调了迭代在处理大量重复计算问题上的优势。
摘要由CSDN通过智能技术生成

在c语言中,递归就是函数自己调用自己。

这里写一个史上最简单的c语言递归代码。

在这里呢,就是main函数自己调用了自己,但是这个代码会进入死循环,也称死递归,导致栈溢出(Stack overflow);这里仅供演示。

递归的思想:

递归就是把一个大的问题层层转换为一个与原问题相识,但是规模较小的问题来求解,直到这个小问题不能再拆分,递归就结束了,所以递归的思考方式是把大事化小的过程;

递归中的递就是递推的意思,归是回归的意思。

递归的限制条件:

当然,我们在使用递归的时候,也要给他加上限制条件,不然他就死递归了。

递归有两个限制条件;

1:递归存在限制条件,当满足这个限制条件时,递归将不再继续。

2:每次函数调用的之后会越来越接近这个条件。

递归举例:

一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘是1。

自然数n的阶乘写成n!

比如说我们想求n的阶乘(不考虑溢出),n的阶乘就是1~n之间数字累积相乘;

比如说5的阶乘就是5x4x3x2x1。

其中n的阶乘公式为n!  =n*(n-1)!

当n == 0的时候,n的阶乘就是1;

所以n的阶乘递归公式如下

这样我们就可以写出函数Fact来求n的阶乘,假设Fact(n)就是求n的阶乘,那么Fact(n-1)就是求n-1的阶乘;

函数如下

测试:

但我们输入5的时候,结果是120;

5x4x3x2x1=120。

画图推演:

迭代:

递归是一种很好的编程技巧,我们只要得到推导公式,就很容易写成递归的形式。

Fact函数是可以产生正确的结果,但是在递归函数调用的过程中涉及一些运行时的开销。

在C语⾔中每⼀次函数调⽤,都要需要为本次函数调⽤在栈区申请⼀块内存空间来保存函数调⽤期间
的各种局部变量的值,这块空间被称为运⾏时堆栈,或者函数栈帧。
函数不返回,函数对应的栈帧空间就⼀直占⽤,所以如果函数调⽤中存在递归调⽤的话,每⼀次递归
函数调⽤都会开辟属于⾃⼰的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间。
所以如果采⽤函数递归的⽅式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢
出(stack overflow)的问题。
所以不想使用递归就得想其他方法,通常就是迭代的方式(循环的方式);
还是计算n的阶乘,用迭代来写
但我们需要求第n个斐波那契数的时候,这个时候递归就不太适合了。
举例:
斐波那契数刚开始给出两个数为1;然后后面的每一个数都是它前两个数的和
比如 1 1 2 3 5 8 13 21……等等
这样我们就可以得出斐波那契数的推导公式为
然后通过推导公式写成递归的形式
但我们求第8个斐波那契数时,刚好为21 。代码也没有问题,

 

但是如果我们要求第50个的话,我们需要很长时间才能得到结果,为什么呢,因为在递归的过程中很多数字都是重复计算了的,递归层次越深,重复计算越多。

画图理解:

测试理解:

这里我们可以看到,在计算第40个斐波那契数时,就3这个数字被重复计算了39088169次。
所以计算斐波那契数,使用递归是不明智的,所以我们要是有迭代的方式
因为斐波那契数是给出的两个数是1,后面的数是它前两个数相加,所以我们依次计算
代码如下
迭代来完成这个代码,效率就会高一点了。
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值