• Home
  • Archives
  Evan的博客
  • Home
  • Archives
  • 面试
  • 原理笔记
  • 项目实践
  • 其他

常见算法思路

2020/10/10 posted in  面试

这篇文章介绍了一些常见的算法思路,包括尾递归优化,回溯剪枝,贪心算法等等。目前还没写完,以后会慢慢扩展更多的算法介绍。

尾递归优化

某个函数的最后一步是调用另一个函数,就称之为尾调用。如果最后一步调用的函数是其本身(递归)就称之为尾递归。

// 正常写法
function factorialA(n) {if (n === 1) return 1
  return n * factorialA(n - 1)
}

// 尾递归优化
function factorialB(n, x) {if (n === 1) return x
  return factorialB(n - 1, n + x)
}

使用尾递归的原因也很简单,防止爆栈。

在 js 中,函数的调用会在内存中形成一个调用记录,保存着当前调用的位置和内部变量。假如一个函数 A,在其内部调用了函数 B,那么将在 A 的调用记录之上建立一个 B 的调用记录,这种形态称之为 ** 调用栈 **

对上面的两个例子来说,第一种写法有自身的调用记录,而最终的执行结果返回的是一个计算值,那么就需要保存 n 这个变量以及参与计算的函数的调用记录

而第二种写法在函数的末尾直接返回函数,对这个函数来说,并没有别的函数记录需要保存,所以调用栈一直都是 1

  • 要开启尾递归需要用严格模式,因为非严格模式下有 arguments 和 func.caller 两个隐式变量会被调用,破坏了尾递归的条件
  • 在新版的 node 中,不再支持尾递归优化,因为尾递归的条件比较苛刻,即没有中间函数调用记录。但是在实际开发过程中开发者很难去判断自己写的代码是否符合这一条件,导致有些时候我们希望尾递归,但是却触发不了 v8 的优化。另一个问题就是尾递归导致执行栈信息丢失,调试和错误信息的收集都变得比较麻烦。因为执行栈永远是 1,也不知道错误是从哪一次调用被抛出

« leetcode 刷题之旅

常见的排序 »

Evan的博客

Evan 的博客 - 非典型码农,bug永动机
Instagram Weibo GitHub Email RSS

Categories

面试 原理笔记 项目实践 其他 JS Vue 性能优化 算法 计算机网络

Recent Posts

  • 从 HTTP 发展历程重学计算机网络
  • 应届前端的逆袭(中)
  • 应届前端的逆袭(上)
  • 应届前端的逆袭(下)
  • 前端面经复盘

Copyright © 2015 Powered by MWeb,  Theme used GitHub CSS.