本章内容

3.1 递归

方法一:使用 while 循环
方法二:使用递归 — 函数调用自己
(递归只是让解决方法更清晰,并没有性能上的优势)

  1. function lookForKey(box) {
  2. for(item in box) {
  3. if(item.isABox) {
  4. lookForKey(item)
  5. } else {
  6. alert('found the key')
  7. }
  8. }
  9. }

3.2 基线条件和递归条件

递归的问题:由于递归函数调用自己,因此编写这样的函数时很容易出现错误,进而导致无限循环。
解决的方式:编写递归函数时,必须告诉它何时停止递归。
每个递归函数的2个组成部分:基线条件(base case)和 递归条件(recursive case)
递归条件: 函数调用自己。
基线条件:函数不再调用自己,从而避免形成无限循环。

  1. def countdown(i):
  2. print i
  3. if i <= 1: /* 基线条件 */
  4. return
  5. else: /* 递归条件 */
  6. countdown(i - 1)

3.3 栈

调用栈 ( call stack )

3.3.1 调用栈

计算机在内部使用被称为调用栈的栈 :::warning 调用函数时,计算机将首先为该函数调用分配一块内存。
变量赋值了,就需要存储到内存中。
每当调用函数时,计算机会将函数调用涉及的所有变量的值存储到内存中。
计算机使用一个栈来表示这些内存块,其中第二个内存块位于第一个内存块上面。
调用函数,从函数调用返回。
此时栈顶的内存块被弹出。
调用另一个函数时,当前函数暂停并处在未完成状态。该函数的所有变量的值都还在内存中。 :::

调用栈:栈用于存储多个函数的变量,被称为调用栈

3.3.2 递归调用栈

递归函数也使用调用栈。