JavaScript之递归
什么是递归?
程序调用自身的编程技巧称为递归( recursion)。递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量 。
一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
求和1···100
function getSum(num) {
if(num === 1) {
return num
} else {
// return num + getSum(num - 1) // 如果 var getterSum = getSum, getSum = null 会报错
return num + arguments.callee(num - 1)
}
}
const value = getSum(1000)
console.log(value)
奇数项 求和
// 第0项为1,第1项为3···
function foo(n){
if(n == 0) return 1;
return foo(n-1) + 2;
} function sum(n){
if(n == 0) return 1;
return foo(n) + sum(n-1);
} console.log(sum(1)) //
偶数项 求和
// 第0项为2,第1项为4···
function fn(n){
if(n == 0) return 2;
return fn(n-1) + 2;
}
function sum(n){
if(n==0) return 2;
return fn(n) + sum(n-1);
}
console.log(sum(1)) //
尾递归
函数在尾部调用自身就成为尾递归。
function factorial(n) {
if(n === 1) return n
return n * factorial(n - 1)
}
// 计算n的阶乘,最多需要保存n个调用记录,复杂度为O(n)
console.time(1)
console.log(factorial(5)) //
console.timeEnd(1) // 1: 1.60400390625ms
// 如果改为尾递归,只需要保留一个调用记录,复杂度为O(1)
function factorial01(n, tntal) {
if(n === 1) return tntal
return factorial(n - 1, n * tntal)
}
console.time(2)
console.log(factorial01(5, 1)) //
console.timeEnd(2) // 2: 0.14404296875ms
Fibonacci(斐波那契)数列
function Fibonacci(n) {
if(n <= 1) return 1
return Fibonacci(n - 1) + Fibonacci(n - 2)
}
console.time(1)
console.log(Fibonacci(20)) //
console.timeEnd(1) // 1: 4.115966796875ms
// console.time(2)
// console.log(Fibonacci(100)) // 10946
// console.timeEnd(2) // stack overflow 堆栈溢出
Fibonacci(斐波那契)数列改写
通过一个正常形式的阶乘函数factorial,调用尾递归函数tailFactorial。
// 尾递归优化
function Fibonacci01(n, ac1 = 1, ac2 = 1) {
if(n <= 1) return ac2
return Fibonacci01(n - 1, ac2, ac1 + ac2)
} console.time(3)
console.log(Fibonacci01(100)) //
console.timeEnd(3) // 3: 0.52197265625ms
柯里化(currying)
通过柯里化,将尾递归函数tailFactorial变为只接受一个参数的factorial。
ES5:
function currying(fn, n) {
return function (m) {
return fn.call(this, m, n);
};
}
function tailFactorial(n, total) {
if (n === 1) return total;
return tailFactorial(n - 1, n * total);
}
const factorial = currying(tailFactorial, 1);
factorial(5) //
ES6:
function factorial(n, total = 1) {
if (n === 1) return total;
return factorial(n - 1, n * total);
}
factorial(5) // 120
JavaScript之递归的更多相关文章
- Javascript中递归造成的堆栈溢出及解决方案
关于堆栈的溢出问题,在Javascript日常开发中很常见,Google了下,相关问题还是比较多的.本文旨在描述如何解决此类问题. 首先看一个实例(当然你可以使用更容易的方式实现,这里我们仅探讨递归) ...
- 每天一个JavaScript实例-递归实现反转数组字符串
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- JavaScript的递归之更多例子
更多例子 第二个递归的例子是求两个自然数的最大公约数(有没有回到令人怀念的中学时代).下面的程序用的是经典的辗转相除法. //greatest common divisor //假定a.b都是正整数 ...
- 前端笔试题目总结——应用JavaScript函数递归打印数组到HTML页面上
数组如下: var item=[{ name:'Tom', age:70, child:[{ name:'Jerry', age:50, child:[{ name:'William', age:20 ...
- JavaScript对象---递归遍历对象
JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象. JavaScript 对象 JavaScript 提供多个内建对象,比如 St ...
- javascript memoization递归优化
memoize优化递归 function createRec(callback, cache) { cache = cache || []; var rec = function(n) { (n in ...
- javascript 将递归转化为循环
function tco(f) { var value; var active = false; var accumulated = []; return function accumulator() ...
- JavaScript 函数递归
递归函数 递归函数是在一个函数通过名字调用自身的情况下构成的 项目中例如树状结构渲染,对象深复制,等很多方面都会使用到递归函数 function factorial(num){ if (num < ...
- JavaScript通过递归合并JSON
通过递归合并JSON: function mergeJSON(o, n) { let oType = Object.prototype.toString.call(o); let nType = Ob ...
- JavaScript利用递归和循环实现阶乘
[实现方法] 1.利用while循环来做,当然for循环也可以. 2.递归 [代码内容] 偷懒,直接用onkeyup事件来限制来页面的输入 循环代码: //第一种方法 while循环 oCount.o ...
随机推荐
- Spark Scheduler 模块(上)
在阅读 Spark 源代码的过程中,发现单步调试并不能很好的帮助理解程序.这样的多线程的分布式系统,更好的阅读源代码的方式是依据模块,分别理解. 在包 org.apache.spark 下面有很多 ...
- 0104 gradle入门
背景 gradle的官网是 www.gradle.org,标题介绍是: accelerate developer productivity,翻译过来:提高开发者的生产率: 简要介绍:从手机app到微服 ...
- java 立方变自身
立方变自身 观察下面的现象,某个数字的立方,按位累加仍然等于自身. 1^3 = 1 8^3 = 512 5+1+2=8 17^3 = 4913 4+9+1+3=17 - 请你计算包括1,8,17在内, ...
- POJ 1330:Nearest Common Ancestors
Nearest Common Ancestors Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 20940 Accept ...
- Ajax学习系列——向服务器发送请求
1.如何发送请求? 如果需要向服务器发送请求,我们使用的是XMLHttpRequest对象中的open()和send()方法. var xhr = new XMLHttpRequest();//具体创 ...
- tornado+peewee-async+peewee+mysql(一)
前言: 需要异步操作MySQL,又要用orm,使用sqlalchemy需要加celery,觉得比较麻烦,选择了peewee-async 开发环境 python3.6.8+peewee-async0.5 ...
- 自己安装windows版本的Flink
参照 https://blog.csdn.net/clj198606061111/article/details/99694033 我自己做一遍 找到对应的网址 https://flink.apach ...
- Docker Ubuntu 例子
版权所有,未经许可,禁止转载 章节 Docker 介绍 Docker 和虚拟机的区别 Docker 安装 Docker Hub Docker 镜像(image) Docker 容器(container ...
- Java入门程序开发
Java入门程序开发 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Java程序开发流程 Java程序开发流程如下: >.将Java代码编写到扩展名为".jav ...
- HDU - 4405 Aeroplane chess(期望dp)
题意:沿着x轴从0走到大于等于N的某处,每一步的步数由骰子(1,2,3,4,5,6)决定,若恰好走到x轴上某飞行路线的起点,则不计入扔骰子数.问从0走到大于等于N的某处的期望的扔骰子次数. 分析: 1 ...