1.分治
将一个难以直接解决的大问题,分割成一些规模较小的K个相同问题,对这些问题分别求解。若这些问题规模仍不够小,再进行划分。如此递归地进行下去,直到问题小到容易解决为止
由此可知,递归是实现分治算法的一种技术方式。
2.递归
直接或间接地调用自身的算法
需要着重解决的问题:
- 递归边界的取舍:递归的出口到底在哪?
- 递归条件(或称递归方程)的分析:如何构成递归关系?
一个优秀好用的递归函数应该在接口处更改变量的值,而不是在函数体内使用语句进行值的变更
理解递归的要点在于放弃!放弃理解和跟踪全程的企图,只理解两层之间的交接以及递归终结的条件
算法举例分析(递归)
1.阶乘函数
依据数学定义,阶乘函数:
n ! = { 1 n=0 n ∗ ( n − 1 ) ! n>0 n!= \begin{cases} 1&\text{n=0}\\ n*(n-1)!&\text{n>0} \end{cases} n!={
1n∗(n−1)!n=0n>0
该定义直观符合递归形式(以较小自变量的函数值表示较大自变量函数值)
其中:
- 递归边界:n=0
- 递归方程:n!=n*(n-1)!
c语言实现:
int factorial(int n){
if(n == 0){
return 1;
}
else{
return n * factorial(n - 1);
}
}
2.Fibonacci数列
无穷数列1,1,2,3,5,8,13,21,34,55……称为Fibonacci数列(又称黄金分割数列,兔子数列)。该数列从第3项开始,每一项都等于前两项之和。其公式为:
F ( n ) = { 1 n=0 1 n=1 F ( n − 1 ) + F ( n − 2 ) n>1 F(n)= \begin{cases} 1&\text{n=0}\\ 1&\text{n=1}\\ F(n-1)+F(n-2)&\text{n>1} \end{cases} F(n)=⎩⎪⎨⎪⎧11F(n−1)+F(n−2)n=0n=1n>1
该定义同样直观符合递归形式。其中:
- 递归边界:n=0或n=1
- 递归方程:F(n)=F(n-1)+F(n-2)
c语言实现:
int fibonacci(int n){
if(n == 0 || n == 1){
return 1;
}
else{
return fibonacci(n - 1) + fibonacci(n - 2);
}
}
3.Ackerman函数
双递归函数:一个函数及它的一个变量由函数自身定义的函数
Ackerman函数是一个增长速度比n!快,比logn慢的多的函数。其定义为:
A ( n , m ) = { A ( 0 , m ) = 1 n=0,m>=0 A ( 1 , 0 ) = 2 n=1, m=0