任何调用自身的函数,都叫递归。
但系,
一定要保证递归能够终止
①.存在不再递归的基本情形
②.问题规模不断变小,最终收敛到基本情形
相关术语
基本情形(base case):函数不再递归嘅情形
递归情形(recursive case):函数调用自身作为子任务执行嘅情况
例如,求n!
假设 int Fact(int n) 为求 n! 的函数
分析情况,当 n=0 或 n=1 时,n! = 1 (基本情形)
当 n > 1时 ,n! = n*(n-1)! (递归情形)
所以
int Fact(int n){
//基本情形
if(n == 1) return 1;
if(n == 0) return 1;
//递归情形
else
return n * Fact(n-1);
}
递归和内存
递归调用会在内存产生新的函数副本,直到函数结束(返回数据),函数副本从内存中删除。
即,
Fun(3) -> Fun(2) -> Fun(1)
1 <- 1 <- return 1
最后删除Fun(3) <- 再删除Fun(2) <- 先删除Fun(1)
递归和迭代
官话:递归比迭代更加简洁易懂。当任务能被相似的子任务定义时,采用递归,即迭代(循环)都可转化为递归函数
递归
1)到达基本情形,必须终止
2)每次递归调用需要额外空间,用于栈帧(内存)开销
3)无穷情况,会栈溢出(耗尽内存),终止程序
迭代
1)循环条件为假,终止
2)迭代不需要额外嘅空间开销
3)出现死循环,无法终止程序
所以,
迭代比递归更有效(函数调用开销),但系,对于某些问题,无明显嘅迭代求解