什么是递归?

目录

一、啥叫递归

二、递归语言例子

三、递归的三大要素

第一要素:明确你这个函数想要干什么

第二要素:寻找递归结束条件

第三要素:找出函数的等价关系式

四、常见案例

案例1:阶乘

案例2:斐波那契数列

 案例3、电影院找座位


一、啥叫递归

聊递归之前先看一下什么叫递归。
递归,就是在运行的过程中调用自己。

构成递归需具备的条件
1. 子问题须与原始问题为同样的事,且更为简单;
2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理。

二、递归语言例子

我们用2个故事来阐述一下什么叫递归。

1,从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?“从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?‘从前有座山,山里有座庙,庙里有个老和尚,正在给小和尚讲故事呢!故事是什么呢?……’”

2,大雄在房里,用时光电视看着从前的情况。电视画面中的那个时候,他正在房里,用时光电视,看着从前的情况。电视画面中的电视画面的那个时候,他正在房里,用时光电视,看着从前的情况……

三、递归的三大要素
 

第一要素:明确你这个函数想要干什么

对于递归,这个函数的功能是什么,他要完成什么样的一件事,而这个,是完全由你自己来定义的。也就是说,我们先不管函数里面的代码什么,而是要先明白,你这个函数是要用来干什么。

例如,我定义了一个函数

// 算 n 的阶乘(假设n不为0)
int f(int n){
 
}

这个函数的功能是算 n 的阶乘。好了,我们已经定义了一个函数,并且定义了它的功能是什么,接下来我们看第二要素。

第二要素:寻找递归结束条件

所谓递归,就是会在函数内部代码中,调用这个函数本身,所以,我们必须要找出递归的结束条件,不然的话,会一直调用自己,进入无底洞。也就是说,我们需要找出当参数为啥时,递归结束,之后直接把结果返回,请注意,这个时候我们必须能根据这个参数的值,能够直接知道函数的结果是什么。

例如,上面那个例子,当 n = 1 时,那你应该能够直接知道 f(n) 是啥吧?此时,f(1) = 1。完善我们函数内部的代码,把第二要素加进代码里面,如下

// 算 n 的阶乘(假设n不为0)
int f(int n){
    if(n == 1){
        return 1;
    }
}

有人可能会说,当 n = 2 时,那我们可以直接知道 f(n) 等于多少啊,那我可以把 n = 2 作为递归的结束条件吗?

当然可以,只要你觉得参数是什么时,你能够直接知道函数的结果,那么你就可以把这个参数作为结束的条件,所以下面这段代码也是可以的。

// 算 n 的阶乘(假设n不为0)
int f(int n){
    if(n <= 2){
        return n;
    }
}

第三要素:找出函数的等价关系式

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

例如,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;
}

四、常见案例

案例1:阶乘

我们先来看一个最简单的递归调用-阶乘,代码如下

    <script>
      // ======================n的阶乘======================
      // n的阶乘:n!=n*(n-1)*...*3*2*1;
      // 1、公式:fn(n)=fn(n-1)*n;(也可写为:fn(n)=n*fn(n-1))
      // 2、终点:fn(1)=1;

      function fn(n) {
        if (n === 1) {
          return 1;
        } else {
          return fn(n - 1) * n;
        }
      }
      console.log(fn(5));
      // 打印上面函数执行之后的返回值。

      // 公式推导:2=2*1; ==> fn(2)=2*fn(1);
      //          3=3*2*1 ==> fn(3)=3*fn(2);
      //          4=4*3*2*1 ==> fn(4)=4*fn(3);
      //          ...
      //          n=n*(n-1)*...*3*2*1 ==> fn(n)=n*fn(n-1);
      // 总结:运用递归思想,找好公式和终点(最重要)。
    </script>

案例2:斐波那契数列

斐波那契数列的是这样一个数列:1、1、2、3、5、8、13、21、34....,即第一项 f(1) = 1,第二项 f(2) = 1.....,第 n 项目为 f(n) = f(n-1) + f(n-2)。求第 n 项的值是多少。

   <script>
      // ==================斐波那契数列==================
      // 斐波那契数列:1、1、2、3、5、8、13、21、34、55、89...
      // 同理:先找公式和终点。
      // ==>从第三位开始,前两位数之和得到自己。
      // 前提:设置n为位数。n表示第n位。
      // 1、公式:fn(n)=fn(n-1)+fn(n-2);
      // 2、终点:fn(1)=1;f(2)=1;
      //        前两位数没有规律,第三位开始规律;双终点。

      function fn(n) {
        if (n === 1 || n === 2) {
          return 1;
        } else {
          return fn(n - 1) + fn(n - 2);
        }
      }
      console.log(fn(7));
    </script>

 案例3、电影院找座位

  <script>
      // ==================电影院找座位(问前排)==================
      // 同理:先找公式和终点。
      // 1、公式:fn(n)=fn(n-1)+1;
      // 2、终点:fn(1)=1;(第一排前面没人了,知道自己是第一排)
      function fn(n) {
        if (n === 1) {
          return 1;
        } else {
          return fn(n - 1) + 1;
        }
      }
      console.log(fn(5));
    </script>

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

燕穗子博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值