什么是递归?
递归是将大问题化为相同结构的小问题,从待求解的问题出发,一直分解到已经已知答案的最小问题为止,然后再逐级返回
注
(1)递归只能在递归函数自身内使用。
(2) 在使用递归时,必须有一个明确的递归结束条件,称为递归出口。
递推 | 把复杂的问题的求解推到比原问题简单一些的问题的求解 |
回归 | 当获得最简单的情况后, 逐步返回, 依次得到复杂的解. |
优点 | 代码更简洁清晰,可读性更好递归可读性好这一点,对于初学者可能会反对。实际上递归的代码更清晰,但是从学习的角度要理解递归真正发生的什么,是如何调用的,调用层次和路线,调用堆栈中保存了什么,可能是不容易。但是不可否认递归的代码更简洁。 |
缺点 | 由于递归需要系统堆栈,所以空间消耗要比非递归代码要大很多。而且,如果递归深度太大,可能会造成栈溢出 |
什么是迭代?
迭代大部分时候需要人为的对问题进行剖析,将问题转变为一次次的迭代来逼近答案。即利用变量的原值推算出变量的一个新值.如果递归是自己调用自己的话,迭代就是A不停的调用B。
迭代与递归比较
递归 | 它重复调用机制,因此重复函数调用的开销很大,将占用很长的处理器时间和大量的内存空间。每次递归调用都要生成函数的另一个副本(实际上只是函数变量的另一个副本).从而消耗大量内存空间。但递归代码简洁清晰,可读性更好。 |
迭代 | 迭代通常发生在函数内,因此没有重复调用函数和多余内存赋值的开销 |
下面我们是一个斐波那契数列的求解的递归和迭代实现实例
fib(0)=0;
fib(1)=1;
fib(n)=fib(n-1)+fib(n-2);
递归版本:
int func(const int n){
if(n>1)
return func(n-1) + func(n-2);
else
return n; // n <=1时给出了明确的递归终止条件
}
迭代实现:
int func(const int n){
int i, tmp0, tmp1, tmp2;
if(n<=1)
return n;
tmp1 = 0;
tmp2 = 1;
for(i = 2; i <= n; i++){
tmp0 = tmp1 + tmp2;
tmp2 = tmp1;
tmp1 = tmp0;
}
return tmp0;
}