什么是递归?

程序调用自身的编程技巧称为递归( 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之递归的更多相关文章

  1. Javascript中递归造成的堆栈溢出及解决方案

    关于堆栈的溢出问题,在Javascript日常开发中很常见,Google了下,相关问题还是比较多的.本文旨在描述如何解决此类问题. 首先看一个实例(当然你可以使用更容易的方式实现,这里我们仅探讨递归) ...

  2. 每天一个JavaScript实例-递归实现反转数组字符串

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  3. JavaScript的递归之更多例子

    更多例子 第二个递归的例子是求两个自然数的最大公约数(有没有回到令人怀念的中学时代).下面的程序用的是经典的辗转相除法. //greatest common divisor //假定a.b都是正整数 ...

  4. 前端笔试题目总结——应用JavaScript函数递归打印数组到HTML页面上

    数组如下: var item=[{ name:'Tom', age:70, child:[{ name:'Jerry', age:50, child:[{ name:'William', age:20 ...

  5. JavaScript对象---递归遍历对象

    JavaScript 中的所有事物都是对象:字符串.数值.数组.函数... 此外,JavaScript 允许自定义对象. JavaScript 对象 JavaScript 提供多个内建对象,比如 St ...

  6. javascript memoization递归优化

    memoize优化递归 function createRec(callback, cache) { cache = cache || []; var rec = function(n) { (n in ...

  7. javascript 将递归转化为循环

    function tco(f) { var value; var active = false; var accumulated = []; return function accumulator() ...

  8. JavaScript 函数递归

    递归函数 递归函数是在一个函数通过名字调用自身的情况下构成的 项目中例如树状结构渲染,对象深复制,等很多方面都会使用到递归函数 function factorial(num){ if (num < ...

  9. JavaScript通过递归合并JSON

    通过递归合并JSON: function mergeJSON(o, n) { let oType = Object.prototype.toString.call(o); let nType = Ob ...

  10. JavaScript利用递归和循环实现阶乘

    [实现方法] 1.利用while循环来做,当然for循环也可以. 2.递归 [代码内容] 偷懒,直接用onkeyup事件来限制来页面的输入 循环代码: //第一种方法 while循环 oCount.o ...

随机推荐

  1. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 字体图标(Glyphicons):glyphicon glyphicon-signal

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  2. centos7安装google-chrome和chromedriver

    1.root用户下进入到etc/yum.repos.d目录下  [root@f7d6b9f2-1291-4d2f-8805-aef94deac9f7 yum.repos.d]# pwd  /etc/y ...

  3. Kafka--生产者

    一个应用程序在很多情况下需要往Kafka写入消息:记录用户的活动(用于审计和分析),记录度量指标,保存日志消息,记录智能家电的信息,与其他应用程序进行异步通信,缓冲即将写入到数据库的数据,等等. 多样 ...

  4. 如何修改 Vmware vRealize Operations Manager Appliance root密码

    开机后,按上下键,选择 中间那一项,在底部增加:init=/bin/bash 进入单用户模式后,输入命令:# passwd root                      #修改root密码,要输 ...

  5. 【pwnable.kr】cmd1

    最近的pwnable都是linux操作系统层面的. ssh cmd1@pwnable.kr -p2222 (pw:guest) 首先还是下载源代码: #include <stdio.h> ...

  6. JavaScript.StringObjec.replace

    //StringObject.replace(/regexp/,newContent); //1当newContent为新字符串,就直接用newContent对匹配的内容进行替换. //2当newCo ...

  7. ssh: connect to host 120.79.26.164 port 22: Connection timed out报错问题

    要是使用阿里云服务器,出现这种错误,一般是端口没有打开.需要在阿里云控制台中设置端口后,即可使用ssh连接.

  8. php知识结构

    PHP的运行环境 连环境都搞不起来,就是你有多么喜欢PHP,那也是白搭,开始我们大多会使用集成环境软件例如xampp,wamp.随着知识的增加慢慢要学会自己搭建运行环境,例如 Linux(Ubuntu ...

  9. ZOJ 3795 Grouping 强连通分量-tarjan

    一开始我还天真的一遍DFS求出最长链以为就可以了 不过发现存在有向环,即强连通分量SCC,有向环里的每个点都是可比的,都要分别给个集合才行,最后应该把这些强连通分量缩成一个点,最后保证图里是 有向无环 ...

  10. 长篇Essay写作凑字数的小技巧

    当一个留学党面对一篇5000字的essay,写一半之后却没法继续~这类的感觉是很多同学无法想象的!此时唯一的一个有效的方法:凑字数!但是essay写作怎么凑字数呢?如何写够5000字essay?下面我 ...