什么是递归?

程序调用自身的编程技巧称为递归( 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. Redis详解(七)——集群

    Redis详解(七)--集群 ​Redis3.0版本之前,可以通过Redis Sentinel(哨兵)来实现高可用 ( HA ),从3.0版本之后,官方推出了Redis Cluster,它的主要用途是 ...

  2. 京东首页如何实现pc端和移动端加载不同的html的?

    进入www.jd.com后代码判断是手机的话就跳转m.jd.com let ua = window.navigator.userAgent.toLocaleLowerCase() let murl = ...

  3. win上java1.7和1.8版本修改环境变量无效.md

    网上找了很多办法都没用. 解决办法: 看看自己 "系统环境变量" 中是不是有 "C:\ProgramData\Oracle\Java\javapath" 这项配 ...

  4. 腾讯X5内核使用详解(X5内核播放器使用如何去除控制栏全屏播放)以及一些注意事项

    例子下载地址 https://www.lanzous.com/i2zsv5g      GIT就不用了麻烦的不行 本人安卓刚学 就上X5内核弄了老长时间由于对maven 和idea不熟悉刚开始导包都是 ...

  5. 072-PHP数组的交集和差集

    <?php $arr1=array(1,3,4,5,34,78,99); //参加第一项竞赛的学生学号数组 $arr2=array(5,6,7,3,56,34,8,9); //参加第二项竞赛的学 ...

  6. 移动MAS短信平台发送短信

    MAS短信平台发送短信分为两种方式 参考文档下载 一.sdk调用 using mas.ecloud.sdkclient; using System; namespace 短信发送 { class Pr ...

  7. idea新建maven web项目

    一.新建maven web项目 二.配置服务器 三.测试运行

  8. Elasticsearch 修改数据

    章节 Elasticsearch 基本概念 Elasticsearch 安装 Elasticsearch 使用集群 Elasticsearch 健康检查 Elasticsearch 列出索引 Elas ...

  9. 第九篇 AJAX

    AJAX 阅读目录(Content) 概述 AJAX常见应用情景 AJAX的优缺点 jQuery实现的AJAX $.ajax参数 AJAX请求如何设置csrf_token 序列化 Django内置的s ...

  10. AVCodec 结构体

    typedef struct AVCodec { // 标示Codec 的名字, 比如,"h264" "h263" 等. const char *name; / ...