目录
一.什么是递归?
就是函数直接或者间接自己调用自己
那么为什么要使用递归呢?
因为递归可以将一个复杂的问题直接进行简化,使得代码比较简洁
看起来递归比较简单,实际上递归是不太好理解的,还需要自己多练来体会递归的思想
二.递归的步骤及原理
(1)首先需要将题目拆分成一个个小问题,并且每个问题的解法都相同
(2)需要找到结束的终点,否则会会出现栈溢出而导致程序无法顺利执行
三.递归求解斐波那契额数列
(1)什么是斐波那契数列
斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……
(2)如何求解指定位的斐波那契数列
首先需要知道斐波那契数列是如何进行求出,原理为:
除了第0位和第1位是固定的,其他都是的求解都是由前两位之和而来。
(3)代码
方法一:
public class Demo{
//递归求斐波那契数列的第n位
public static int fibo(int n){
if(n==1 || n==0){
return n;
}
return fibo(n-1)+fibo(n-2);
}
public static void main(String[] args) {
System.out.println(fibo(9));//34
}
}
但是上面虽然能够解决这个问题,但是效率很慢,这是因为它在进行递归调用时对一些已经算出的会进行重复计算,下面举例一个求第5位的递归操作
可以在图中看出,对于3和2中间调用了多次,如果计算一个较大的数可能会出现运行速度时间长,甚至可能会出现栈溢出的问题,那么有没有另一种递归的方法求解这个问题呢,那就是使用尾递归来进行求解
方法二:尾递归进行求解
什么是尾递归?
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。尾递归函数的特点是在回归过程中不用做任何操作。
尾递归调用相当于每一次都在保存之前调用的结果,而且每一次都不会再保存之前的栈帧,每次调用完后会覆盖之前的栈帧从而节省了重新开辟栈帧的代价,所以比较高效。
下图所示,对于递归调用所开辟的栈和运行的次数明显少的多了
代码实现:
public class Demo{
//尾递归求解斐波那契数列
public static int fiboLast(int n,int a,int b){
if(n<=2){
return b;
}else{
return fiboLast(n-1,b,a+b);
}
}
public static void main(String[] args) {
System.out.println(fiboLast(9,1,1));//34
}
}
结果还是为34.
四.递归求解小青蛙跳台阶
(1)什么是小青蛙跳台阶?
问题简述:一只青蛙一次可以跳上1阶台阶,也可以跳上2阶。求该青蛙跳上一个n级的台阶总共需要多少种跳法?
(2)如何进行求解该问题
还可以这样思考,
如果要跳到第n阶,那么必然会落到n-1阶处和n-2阶处两种可能,那么只需要求出所有跳到第n-1阶的结果加上跳到第n-2阶的结果就是最终结果
如果跳到n-1阶,最终必然会落到第n-2阶和第n-3阶处,然后需要求出所有跳到n-2和n-3阶处的结果并相加就会得到结果
通过这样分析,很明显这是一个递归,可能会有人这样认为,需要跳到第n阶时,在第n-1阶只有一种跳法,在第n-2阶处有两种跳法,认为这样最终的结果还要加上2,这样是不对的,因为当我们到第n-1阶时已经将从第n-2阶处跳1阶的结果加上了,这里所说的到n-1阶是最后所有的跳法都到了n-1阶,所以不用加2.
代码实现:
public class Demo{
//青蛙跳台阶
public static int frogStep(int n){
if(n<=3){
return n;
}
return frogStep(n-1)+frogStep(n-2);
}
public static void main(String[] args){
System.out.println(frogStep(5));//8
}
}
既然该问题与斐波那契数列相似,那么也可以使用尾递归的方法来进行求解
代码如下:
public class Demo{
//尾递归求解青蛙跳台阶
public static int frogStepLast(int n,int a,int b){
if(n<2){
return b;
}
return frogStepLast(n-1,b,a+b);
}
public static void main(String[] args){
System.out.println(frogStepLast(5,1,1));//8
}
}