.目录
1.什么是递归
2.递归的限制条件
3.递归的举例
4.递归与迭代
1.递归是什么?
递归是学习c语言函数绕不开的一个话题,那什么是递归呢?
递归其实是一种解决问题的方法,在C语言中,递归就是函数自己调用自己。如:
上面是一个简单的递归程序,只不过上面的递归只是为了演示递归的基本形式,不是为了解决问题,最终会导致栈溢出(stack overflow)。递归的思想:
把一个大的复杂的问题转化成规模较小的子问题来求解;知道子问题不能再被拆分,递归就结束了。所以其思想就是把大事化小的过程。
递归中的递就是递推的意思,归就是回归的意思。
2.递归的限制条件
递归在书写时,有两个必要条件:
• 递归存在限制条件,当满⾜这个限制条件的时候,递归便不再继续。
• 每次递归调⽤之后越来越接近这个限制条件。
3.递归举例
3.1 举例1:求n的阶乘
计算n的阶乘,n的阶乘就是1到n的数字累积相乘。
3.1.1 分析和代码实现
我们知道n的阶乘的公式:n! = n * (n - 1)!
n! --->n * (n-1)!
(n-1)!--->(n-1)*(n-2)!……直到n是1或者是0时,不再拆解
n的阶乘的递归公式如下:
函数如下:
运行结果
3.1.2 画图推演
3.2 举例2:顺序打印一个整数的每一位
输入一个整数m,打印这个按照顺序打印整数的每一位。
比如:
3.2.1 分析和代码实现
分析:
1234%10得到4,然后1234/10得到123,这就相当于去掉了4
然后继续对123%10,就得到了3,再除10去掉3,以此类推
代码如下:
输入和输出结果:4.递归和迭代
在C语⾔中每⼀次函数调⽤,都要需要为本次函数调⽤在栈区申请⼀块内存空间来保存函数调⽤期间 的各种局部变量的值,这块空间被称为运⾏时堆栈,或者函数栈帧。 函数不返回,函数对应的栈帧空间就⼀直占⽤,所以如果函数调⽤中存在递归调⽤的话,每⼀次递归 函数调⽤都会开辟属于⾃⼰的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间。 所以如果采⽤函数递归的⽅式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出(stack overflow)的问题。
比如计算n的阶乘·可以不使用递归的方式:
事实上,我们看到的许多问题是以递归的形式进行解释,这只是因为它比非递归的形式更加清晰,但是这些问题的迭代实现往往比递归实现的效率高。
当一个问题难以用迭代的方式实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开销。
举例3:求第n个斐波那契数
很容易写成递归数列
但是当n输入为50时,需要很长时间才能算出结果,这个计算所花费的时间是很难接受的,说明递归是非常低效的。这时我们可以不用函数递归的方式。如:
完