一、初识递归
程序调用自身的编程技巧称为递归( recursion)。 一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
一般来说,递归需要满足三要素:
- 边界条件;
- 递归前进段;(规模缩小)
- 递归返回段。
当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
二、递归深度学习
1、通过实例1:求解n!来学习递归算法的实现
实例1:求解n!(递归实现)
#include <stdio.h>
int fac(int n)
{
if(n==0||n==1)
{
return 1;
}
else
{
return n*fac(n-1);
}
}
int main()
{
int t;
t=fac(5);
printf("%d\n",t);
}
运行结果:
我们通过递归已经成功实现求n!,那它的过程是怎样的呢?接下来通过图1来向大家展示
虽然递归能够实现5!,但是递归也有一定的局限性。由于栈是由系统自行管理,windows分配的内存大小是1M,所以当数据过于庞大,过程过于复杂时,可能会超出内存空间,程序就会崩溃 。此时我们可以通过循环来实现。
求解n!(for循环实现)
#include <stdio.h>
int fac2(int n)
{
int res=1;
int i;
if(n==0)
{
res=1;
}
else
{
for(i=1;i<=n;i++)
{
res*=i;
}
}
return res;
}
int main()
{
int t;
t=fac2(5);
printf("%d\n",t);
return 0;
}
运行结果:
三、递归和循环的优缺点比较
1、递归
优点:代码简洁、清晰,并且容易验证正确性。
缺点:
- 它的运行需要较多次数的函数调用,每一次函数调用,都需要在内存栈中分配空间以保存参数、返回地址以及临时变量,如果调用层数比较深,需要增加额外的堆栈处理(还有可能出现堆栈溢出的情况)
- 往栈中压入数据和弹出数据都需要时间,如果调用层数比较深,会造成时间消耗,效率降低。
2、循环
优点:速度快(效率高),结构简单,没什么额外开销。
缺点:不容易理解,编写复杂问题时困难