当前位置:   article > 正文

什么是递归?

递归

目录

一、啥叫递归

二、递归语言例子

三、递归的三大要素

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

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

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

四、常见案例

案例1:阶乘

案例2:斐波那契数列

 案例3、电影院找座位


一、啥叫递归

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

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

二、递归语言例子

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

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

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

三、递归的三大要素
 

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

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

例如,我定义了一个函数

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

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

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

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

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

  1. // 算 n 的阶乘(假设n不为0)
  2. int f(int n){
  3. if(n == 1){
  4. return 1;
  5. }
  6. }

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

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

  1. // 算 n 的阶乘(假设n不为0)
  2. int f(int n){
  3. if(n <= 2){
  4. return n;
  5. }
  6. }

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

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

例如,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)。

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

四、常见案例

案例1:阶乘

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

  1. <script>
  2. // ======================n的阶乘======================
  3. // n的阶乘:n!=n*(n-1)*...*3*2*1;
  4. // 1、公式:fn(n)=fn(n-1)*n;(也可写为:fn(n)=n*fn(n-1))
  5. // 2、终点:fn(1)=1;
  6. function fn(n) {
  7. if (n === 1) {
  8. return 1;
  9. } else {
  10. return fn(n - 1) * n;
  11. }
  12. }
  13. console.log(fn(5));
  14. // 打印上面函数执行之后的返回值。
  15. // 公式推导:2=2*1; ==> fn(2)=2*fn(1);
  16. // 3=3*2*1 ==> fn(3)=3*fn(2);
  17. // 4=4*3*2*1 ==> fn(4)=4*fn(3);
  18. // ...
  19. // n=n*(n-1)*...*3*2*1 ==> fn(n)=n*fn(n-1);
  20. // 总结:运用递归思想,找好公式和终点(最重要)。
  21. </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 项的值是多少。

  1. <script>
  2. // ==================斐波那契数列==================
  3. // 斐波那契数列:1、1、2、3、5、8、13、21、34、55、89...
  4. // 同理:先找公式和终点。
  5. // ==>从第三位开始,前两位数之和得到自己。
  6. // 前提:设置n为位数。n表示第n位。
  7. // 1、公式:fn(n)=fn(n-1)+fn(n-2);
  8. // 2、终点:fn(1)=1;f(2)=1;
  9. // 前两位数没有规律,第三位开始规律;双终点。
  10. function fn(n) {
  11. if (n === 1 || n === 2) {
  12. return 1;
  13. } else {
  14. return fn(n - 1) + fn(n - 2);
  15. }
  16. }
  17. console.log(fn(7));
  18. </script>

 案例3、电影院找座位

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/916640
推荐阅读
相关标签
  

闽ICP备14008679号