递归

1. 递归三大要素

明确函数的功能

这个函数到底想要干嘛

寻找递归结束的条件

  • 递归会在函数内部不断地调用函数本身,如果不指定终止条件,它就会一直执行下去
  • 找出当参数为啥时,递归结束,之后直接把结果返回,请注意,这个时候我们必须能根据这个参数的值,能够直接知道函数的结果是什么
// 算 n 的阶乘(假设n不为0)
int f(int n){
    if(n == 1){
        return 1;
    }
}

找出函数的等价关系式

通过不断缩小参数的范围,缩小之后,我们可以通过一些辅助的变量或者操作,使原函数的结果不变。

例如,f(n) 这个范围比较大,我们可以让 f(n) = n * f(n-1)。这样,范围就由 n 变成了 n-1 了,范围变小了,并且为了原函数f(n) 不变,我们需要让 f(n-1) 乘以 n。

说白了,就是要找到原函数的一个等价关系式,f(n) 的等价关系式为 n * f(n-1),即

f(n) = n * f(n-1)。

// 算 n 的阶乘(假设n不为0)
int f(int n){
    if(n <= 2){
        return n;
    }
    // 把 f(n) 的等价操作写进去
    return f(n-1) * n;
}

2. 递归实例

斐波那契数列

int f(int n){
    // 1.先写递归结束条件
    if(n <= 2){
        return n;
    }
    // 2.接着写等价关系式
    return f(n-1) + f(n - 2);
}

小青蛙跳台阶

一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。

  • 第一想法 递归结束的条件是:当n=1时,result=1;
  • 接下来思考怎么找递推关系式,即f(n)怎么写成f(n-1)的形式
    当每次跳的时候,小青蛙可以跳一个台阶,也可以跳两个台阶,也就是说,每次跳的时候,小青蛙有两种跳法。

第一种跳法:第一次我跳了一个台阶,那么还剩下n-1个台阶还没跳,剩下的n-1个台阶的跳法有f(n-1)种。
第二种跳法:第一次跳了两个台阶,那么还剩下n-2个台阶还没,剩下的n-2个台阶的跳法有f(n-2)种。

所以,f(n) = f(n-1) + f(n-2)

Wait! 这个关系式当n = 1的时候,会调用f(-1),从而使程序陷入死循环,所以应该修改终止条件如下:

int f(int n){
    //f(0) = 0,f(1) = 1,等价于 n<=2时,f(n) = n。
    if(n <= 2){
        return n;
    }
    return f(n-1) + f(n-2);
}

参考

[1] 为什么你学不会递归?告别递归,谈谈我的一些经验

posted @ 2020-12-23 12:45  _一只土拨鼠  阅读(110)  评论(0)    收藏  举报