递归就是直接或间接调用自身的算法,把一个的大问题分解成同类的小问题。
递归说到底是函数调用,会有一些函数调用的开销,但现代编译器一般都会对递归进行优化,其效率不一定就比循环差。
递归与循环可以相互转化。
下面是斐波那契数列第n个值的实现:
循环:
int fab(int n)
{
assert(n>0); // n大于0
if(n <= 2) // a1=1, a2=1
return 1;
int a1 = 1, a2 = 1, an = 0; //n>2时
for(int i = 0; i < n - 2; ++i) //a1,a2已知,循环n-2次
{
an = a1 + a2;
a1 = a2;
a2 = an;
}
return an;
}
递归:
int fab_r(int n)
{
assert(n>0);
if(n <= 2) // a1=1, a2=1
return 1;
return fab_r(n-1) + fab_r(n-2); // a(n) = a(n-1) + a(n-2)
}
可以看出,递归比循环在思路上更清晰,大问题分解成小问题。循环代码量比较长,也比较难懂。
递归算法 和循环算法总结
1. 一般递归调用可以处理的算法,也通过循环去解决常需要额外的低效处理 。
2. 现在的编译器在优化后,对于多次调用的函数处理会有非常好的效率优化,效率未必低于循环。
3.能用循环就用循环,毕竟在大多数情况下效率高一些,用循环解决不也时,考虑用递归。