7.3 递归与迭代
7.3.1 练习3:
求 n 的阶乘。(不考虑溢出)
7.3.2 练习4:
求第 n 个斐波那契数。(不考虑溢出)
//在我们自己能写出函数的时候,递归是很简单的,只是说有时候不能写出函数就会难想一点,但也都是个熟能生巧的过程哈!
但是我们发现 有问题 ;
在使用 fib 这个函数的时候如果我们要计算第 50 个斐波那契数字的时候特别耗费时间。
使用 factorial 函数求 10000 的阶乘(不考虑结果的正确性),程序会崩溃。
为什么呢?
最后我们输出看看 count ,是一个很大很大的值。
那我们如何改进呢?
在调试 factorial 函数的时候,如果你的参数比较大,那就会报错: stack overflow (栈溢出)
这样的信息。
系统分配给程序的栈空间是有限的,但是如果出现了死循环,或者(死递归),这样有可能导致一
直开辟栈空间,最终产生栈空间耗尽的情况,这样的现象我们称为栈溢出。
那如何解决上述的问题:
1. 将递归改写成非递归。
2. 使用 static 对象替代 nonstatic 局部对象。在递归函数设计中,可以使用 static 对象替代
nonstatic 局部对象(即栈对象),这不
仅可以减少每次递归调用和返回时产生和释放 nonstatic 对象的开销,而且 static 对象还可以保
存递归调用的中间状态,并且可为 各个调用层所访问。
比如,下面代码就采用了,非递归的方式来实现:
// 求 n 的阶乘 int factorial ( int n ) { int result = 1 ; while ( n > 1 ) { result *= n ; n -= 1 ; } return result ; } // 求第 n 个斐波那契数
提示:
1. 许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更为清晰。
2. 但是这些问题的迭代实现往往比递归实现效率更高,虽然代码的可读性稍微差些。
3. 当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开 销。
最后的最后,函数部分的内容就完成了哈!(当然后面进阶c语言的时候又会再细讲),今天的内容是有点难的,可能更多的是要去理解,嵌套调用,链式访问,递归,迭代好好理解,知道他每一步干什么,他的走向,其实就不会感觉那么难了哈!希望大家慢慢去思考。
要是觉得这篇文章对你有用的话,就来一个点赞加关注吧!!!
感谢观看!!!
最后祝我们一起变好!!!