js递归函数递归思想
定义:
1、递归函数就是在函数体内调用本函数;
2、递归函数的使用要注意函数终止条件避免死循环,使用递
归的时候必须有一个结束标志,否则会报内存溢出的错误 Maximum call stack size exceeded;
为什么使用递归:
递归是编程算法的一种,通过调用自身,将一些复杂/抽象的问题简单化,便于得出解决方案。
先看一道题:
例题:某人需要走上10级台阶,有两种走法,走法A:一步1个台阶;走法B:一步2个台阶。两种走法可以任意交替使用,问走上10级台阶共有多少种方法?
。。。。。。这道题看起来是不是很无头绪,利用递归思想来解决这道问题就简单多了,先看看递归怎么使用。
递归步骤
- 写好递归函数
- 寻找递推关系
- 将递推关系的结构转换为递归体
- 将临界条件加入到递归体中
例题1:计算n的阶乘(数学公式:n!=1×2×3×…×(n-1)×n)
- 写好递归函数:计算n的阶乘可表达为:fn(n)
- 寻找递推关系:根据数学公式:n!=1×2×3×…×(n-1)×n
(n-1)!为 1×2×3×…×(n-1),可得n!阶乘和(n-1)!的关系为(n-1)!*n - 将递推关系的结构转换为递归体:用函数表示即:fn(n) = fn(n-1)*n,
function fn(n){return fn(n-1)*n
}
- 将临界条件加入到递归体中(若没有终止条件,函数会继续计算f(0) 、f(-1) 、f(-2) ··· 从而进入死循环,无法得出结果。):
function fn(n){if(n===1){return 1}return fn(n-1)*n
}
例题2:斐波那契数列
示例:0 1 1 2 3 5 8 13 21…
- 写好递归函数
第n个值可表达为fn(n) - 寻找递推关系
根据多年的上课打盹的经验,可以看出21为前两个值8+13的和,13为5+8的值,即:fn(n) = fn(n-1) + fn(n-2) - 将递推关系的结构转换为递归体
function fn(n){return fn(n-1) + fn(n-2)
}
- 将临界条件加入到递归体中
fn(n)临界值为fn(0),若越过的话,会执行f(-1) 、f(-2) ··· 从而进入死循环,无法得出结果
(n-1) = 0;(n-2)=0,临界值:1,2;即:f(1) = 0,f(2) = 1
function fn(n){if(n<2)return 0if(n<3)return 1return fn(n-1) + fn(n-2)
}
如果进一步求数列的和,你知道怎么用递归表示了?
function fn(n){if(n<2)return 0if(n<3)return 1return fn(n-1) + fn(n-2)
}
// sum(n) = sum(n) +第n个的值(fn(n))
function sum(n){if(n<2)return 0return sum(n-1)+fn(n)
}
现在回过头了分析一下楼梯走法问题:
楼梯走法
某人需要走上10级台阶,有两种走法,走法A:一步1个台阶;走法B:一步2个台阶。两种走法可以任意交替使用,问走上10级台阶共有多少种方法?
我们尝试从递归的角度分析一下
当走上第10级台阶只差最后一步时,存在有两种可能:
第1种:从 第8级 —> 第10级(一步2个台阶)
第2种:从 第9级 —> 第10级(一步1个台阶)
即:10级台阶走法 = 9级台阶走法 + 8级台阶走法
递归关系为:f(10) = f(9)+f(8),f(n) = f(n-1)+f(n-2)
将递推关系的结构转换为递归体:
function fn(n){return fn(n-1) + fn(n-2)
}
1级台阶时,走法只有1种(1步1台阶)
2级台阶时,走法只有2种(1步1台阶或者两步一台阶)
加入临界条件
function fn(n){if(n<3)return nreturn fn(n-1) + fn(n-2)
}
思考
fn(10) = fn(9)+fn(8);
fn(9) = fn(8)+fn(7)…以此类推,你会发现发fn(8)重复执行了两次,以f(10)为例子,用图来表示执行过程:
这么看就很直观了(相同颜色表示同一个函数)
由此我们可以发现递归的问题所在了吧,递归存在性能问题。递归层级越庞大,会极大消耗了系统的性能。经过测试楼梯问题那个递归函数最多可计算至 f(45),而且随着n值越大,计算时间越长。
这时候循环算法就用得上了。
根据我们前面的推导
1级台阶 ==> 走法:1
2级台阶 ==> 走法:2
3级台阶 ==> 走法:1 + 2 = 3
4级台阶 ==> 走法:2 + 3 = 5
5级台阶 ==> 走法:3 + 5 = 8
6级台阶 ==> 走法:5 + 8 = 13
7级台阶 ==> 走法:8 + 13 = 21
即,只要知道前两项(1级台阶和2级台阶)的结果,就可以自底向上依次推算出后面所有项的结果
于是便可以写出 循环函数
function fn(n){if(n<3){return n;}var left = 1; // 左边的数据var right = 2; // 右边的数据var sum = 0;for(var i = 3 ; i <= n ; i++){ // 循环从第3项开始(临界条件)sum = left + right; // 计算前一次左右数据的和left = right; // 把前一次的right赋值给下一次的leftright = sum; // 把前一次的和赋值给下一次的right}return sum;
}
那为什么又要用递归了,像走楼梯这种抽象问题,我们可以用递归思想将抽象问题逐步简单化,再用递归反向推导出循环过程。
循环算法解决了递归消耗系统性能的问题,可以计算任意数值(当数值太大超出JavaScript数值范围时,返回 Infinity)。
js递归函数递归思想相关推荐
- Javascript函数之深入浅出递归思想,附案例与代码!
作者 | 浮世万千吾爱有三 责编 | Carol 来源 | CSDN 博客 递归函数的理解 1.生活中的递归 "递归"在生活中的一个典例就是"问路".如图小哥哥 ...
- js递归函数使用介绍
所谓的递归函数就是在函数体内调用本函数. 使用递归函数一定要注意,处理不当就会进入死循环.递归函数只有在特定的情况下使用 ,比如阶乘问题 一个10以内的阶乘,js递归函数实例代码: <!DOCT ...
- js中递归调用返回值为undefined问题
js中递归调用返回值为undefined问题 问题重现 下面这个简单的递归函数 理论上弹出的是11 但是............. 问题解决 在函数调用处加return
- 汉诺塔问题(递归思想)(堆栈学习)
#include<stdio.h>//汉诺塔问题运用到递归思想, int num=0 ;//首先要给大家介绍一下堆栈 //想象一下,有一个递归函数当他执行自己本身的程序时 //因为条件满足 ...
- C++两个函数可以相互递归吗_通俗讲:数据结构递归思想
通俗讲:数据结构递归思想 脑容量有限,拒绝花里胡哨 一个递归求阶乘的例子 #如5的阶乘 f(6)=6*5*4*3*2*1 def f(int n) {if n <= 0 : return 1re ...
- 如何用递归思想 求n的阶乘 C语言
如何用递归思想 求n的阶乘 C语言 首先,我讲一下什么是递归? 一个函数在它的函数体内调用它自身称为递归调用,这种函数称为递归函数.执行递归函数将反复调用其自身,每调用一次就进入新的一层,当最内层的函 ...
- php中的递归思想,PHP 递归和递推思想
递归思想(递归函数): 递归思想的一个基本形式是在一个函数中,有至少一条语句,又会去调用该函数自身.(求n!问题用递归:杨辉三角问题用过递归-) funtion digui($n){ if($n==1 ...
- day16:递归思想——Fibonacci 斐波那契数列
一.斐波那契数列(Fibonacci sequence),又称黄金分割数列,这个数列最早是由印度数学家提出来的. 该序列的前几项是这样的:0,1,1,2,3,5,8,13,21,34,⋯ 在数学上,斐 ...
- Python 二分查找(涉及递归思想)
二分查找介绍 二分查找(搜索)是一种在有序列表中查找某一特定元素的搜索算法. 首先先查找到目标列表的中间元素,如果中间元素正好是要查找的元素,则返回查找元素的索引下标,搜索结束:如果要查找的元 ...
最新文章
- Java学习笔记二十:Java中的内部类
- 【12】行为型-观察者模式
- 无头虚拟化服务器,VBoxHeadless - 使用VirtualBox 4.0在无头Ubuntu 10.10服务器上运行虚拟机...
- 海康开放平台音视频方案对比(rtsp、http-flv、hls、rtmp)
- 计算机网络资料篇(二)——快速理解网络协议
- EL表达式 参考手册
- 使用Netbeans开发App Engine Java
- 文本编辑器nano使用
- 转录组分析_转录组+?分析+?实验=2区文章
- string转int/float/double、int/float/double转string、转字符串数组的方法:stoi、stringstream、scanf、to_string、sprintf
- NLP学习—22.Transformer的代码实现
- 从0到100亿互联网金融架构发展史
- 新手如何备考GRE考试作文
- 粒子群优化算法求解函数最值
- 80x86汇编小站-公告
- ubuntu 中 vi 编辑文件上下左右删除键毫无作用肿么办!(上上下下左右左右BABA)
- js中undefined
- mac port更新卡住
- Android 布局旋转 横屏竖屏
- C++ 算电费 题解