《数据结构与算法》5-递归

递归是一种算法,算法是对计算规律的总结,递归适用于什么样的计算呢。

  • 可分解的计算,即总的计算公式可以分解为几个小的计算公式
  • 重复性的计算,没有重复性就不能归纳出基本计算单元
  • 有退出计算的条件,就是说到某个条件满足的时候会退出计算

现实中有没有递归的场景呢,想象这么一种场景,推荐好友获取积分的规则,当A-推荐B,B-推荐C,C推荐D。要找到D的最终推荐人,就要一步一步回溯C/B然后找到A。

再抽象一点。总共10个台阶,每次可以上一个台阶,或者两个台阶。总共有多少种走法?

f(n) = f(n-1)+f(n-2);
f(1) = f(1-1) = 1;
f(2) = f(2-1)+f(2-2) = 2;

如果n>2的时候,可以分为上一级和上两级两种走法,所以f(n) = f(n-1) + f(n-2)

但是当剩下一级台阶,只有一种走法,剩两个台阶的时候有两种走法。

所以10个台阶的计算方法是

    public static void main(String[] args) throws JSONException {

       int methods = caculate(10);

        System.out.println(methods);
    }

    private static int caculate(int i) {
        if(i==2){
            return 2;
        }
        if(i==1){
            return 1;
        }
        return caculate(i-1)+caculate(i-2);
    }

上面就是台阶走法的计算公式。

递归的好处就是把频繁的方法调用改为调用自身。直到满足条件退出

坏处是

  • 难以理解,有时候很难理解栈的计算逻辑
  • 在java语言中,虚拟机栈有有深度限制,如果我们的递归层次特别的深,会爆出栈溢出的异常。因为每次方法的调用,会把调用方的变量信息保存为栈帧信息压入栈。上面一节栈中我们总结栈是一种有深度的线性表,如果栈特别的深,会占用大量的空间。

为了预防栈溢出,我们可以限制栈的深度,比如

递归有简洁明了的好处,但是还是要谨慎使用,可以把未知深度的递归转换为非递归算法。

比如for循环解决递归问题

猜你喜欢

转载自blog.csdn.net/David_lou/article/details/108640332