zoukankan      html  css  js  c++  java
  • 尾递归

    一、什么是尾调用?

    尾调用的概念非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。

    function f(x){
      return g(x);
    }

    二、尾调用优化

    函数在调用的时候会在调用栈(call stack)中存有记录,每一条记录叫做一个调用帧(call frame),每调用一个函数,就向栈中push一条记录,函数执行结束后依次向外弹出,直到清空调用栈,参考下图:

    function foo () { console.log(111); }
    function bar () { foo(); }
    function baz () { bar(); }
    
    baz();
    call stack

    造成这种结果是因为每个函数在调用另一个函数的时候,并没有 return 该调用,所以JS引擎会认为你还没有执行完,会保留你的调用帧。

    如果对上面的例子做如下修改:

    function foo () { console.log(111); }
    function bar () { return foo(); }
    function baz () { return bar(); }
    
    baz();

    二、什么是尾递归?

    前面我们知道了尾调用的概念,当一个函数尾调用自身,就叫做尾递归。

    function foo () {
        return foo();
    }

    那么尾递归相比递归而言,有哪些不同呢?
    我们通过下面这个求阶乘的例子来看一下:

    function factorial (num) {
        if (num === 1) return 1;
        return num * factorial(num - 1);
    }
    
    factorial(5);            // 120
    factorial(10);           // 3628800
    factorial(500000);       // Uncaught RangeError: Maximum call stack size exceeded

    如果用尾递归来计算阶乘呢?

    'use strict';
    
    function factorial (num, total) {
        if (num === 1) return total;
        return factorial(num - 1, num * total);
    }
    
    factorial(5, 1);                // 120
    factorial(10, 1);               // 3628800
    factorial(500000, 1);           // 分情况
    
    
    
    ps:值得注意的是,虽然说这里启用了严格模式,但是经测试,在Chrome和Firefox下,还是会报栈溢出错误,并没有进行尾调用优化
    Safari浏览器进行了尾调用优化,factorial(500000, 1)结果为Infinity,因为结果超出了JS可表示的数字范围
    如果在node v6版本下执行,需要加--harmony_tailcalls参数,node --harmony_tailcalls test.js
    node最新版本已经移除了--harmony_tailcalls功能

    博主试了一下,下面这个函数,最多可以到 12578 次递归
    function F(n) {
      if (n>12577) return n;
      return F(n+1);
    }


  • 相关阅读:
    优达学城数据分析师纳米学位——知识点总结1
    优达学城数据分析师纳米学位——第二课 jupyter notebook的使用
    优达学城数据分析师纳米学位——第一课总结
    产品经理学习笔记- 猿题库运营面试准备
    EXCEL 2010学习笔记—— 动态图表
    EXCEL 2010学习笔记 —— VLOOKUP函数 嵌套 MATCH 函数
    最长上升子序列模板
    不要62
    划分树简单介绍
    母函数基本应用
  • 原文地址:https://www.cnblogs.com/amiezhang/p/10143067.html
Copyright © 2011-2022 走看看