递归函数,在不使用全局变量

时间:2016-06-19 20:17:20

标签: javascript recursion ecmascript-6

我正在编写函数来序列化和反序列化二叉树(只是将它转换为数组并返回到BT)而且我很难编写反序列化函数而不使用全局变量来跟踪索引。

我的Node类看起来像这样:

class Node {
  constructor(value) {
    this.value = value
    this.left = null
    this.right = null
  }
}

我的序列化方法如下所示:

function serialize(node = this, list = []) {
  if (!node) {
    list.push('#')
    return
  }

  list.push(node.value)
  serialize(node.left, list)
  serialize(node.right, list)
  return list
}

这是我的问题,在deserialize函数中我必须为'index'保留一个全局变量,有没有办法保持索引的全局值而不创建全局变量?

let index = 0

function deserialize(list) {
  if (index === list.length || list[index] === '#') {
    index++
    return
  }

  const tree = new Node(list[index])
  index++

  tree.left = deserialize(list)
  tree.right = deserialize(list)

  return tree
}

我最初写的函数是这样的:(但我必须将索引变量重构为全局变量)

function deserialize(list, index = 0) {
  if (index === list.length || list[index] === '#') {
    index++
    return
  }

  const tree = new Node(list[index])
  index++

  tree.left = deserialize(list, index)
  tree.right = deserialize(list, index)

  return tree
}

这最终得到了一个对称树,因为tree.left和tree.right总是采用相同的索引。

我很好奇是否有一种简单的方法可以在纯粹的递归函数中跟踪索引(不使用递归子例程)而不创建全局变量。

2 个答案:

答案 0 :(得分:4)

这样做的一般方法:

function wrapperFunction(args) {
  var bookkeepingStuff = whatever;
  function actualRecursiveFunction(args) {
    // code
  }

  return actualRecursiveFunction(args);
}

将真正的递归函数包装在另一个函数中。包装器的任何局部变量都有效地类似于嵌套在里面的真实递归函数的全局变量。

答案 1 :(得分:3)

传递一个警棍,其中包含您可以在递归时更新的成员:

function deserialize(list, baton={index: 0}) {
  var b = baton;  // shorthand
  if (b.index === list.length || list[b.index] === '#') {
    b.index++;
    return;
  }

  const tree = new Node(list[b.index]);
  b.index++;

  tree.left = deserialize(list, b);
  tree.right = deserialize(list, b);

  return tree;
}