javascript - 将具有本地状态的递归函数转换为使用堆栈

标签 javascript recursion data-structures stack

我知道如何使用堆栈转换简单的递归函数(如描述的 here ),但是,一些递归函数有一个棘手的部分,我不知道如何实现。更简单的递归函数不会更改调用者局部变量(调用者是指调用自身的函数)或者换句话说,更简单的递归函数不会根据调用自身的返回值更改其局部变量,但是当它变得棘手时它需要改变它,我不知道如何用堆栈实现做同样的事情。这是一个简化的示例:

const obj = {
  src: {
    size: 0,
    children: {
      api: {
        size: 0,
        children: {
          api_2: {
            size: 0,
            children: {
              'file1.js': {
                size: 2,
              },
              'file2.js': {
                size: 2,
              },
            },
          },
          api_1: {
            size: 0,
            children: {
              'test1.js': {
                size: 1,
              },
              'test2.js': {
                size: 1,
              },
            },
          },
        },
      },
    },
  },
};

const recursive = (object) => {
  if (object.children) {
    const currentChildren = object.children;
    Object.entries(currentChildren).forEach(([, child]) => {
      object.size += recursive(child);
    });
    return object.size;
  } else {
    return object.size;
  }
};

recursive(obj.src);

console.log(obj.src.size);
console.log(obj.src.children.api.size);
console.log(obj.src.children.api.children.api_1.size);
console.log(obj.src.children.api.children.api_2.size);

// Output: 6 6 2 4

如果我的问题令人困惑,只需用堆栈实现这个递归函数就可以帮助我理解我的问题。

最佳答案

您可以使用堆栈的深度优先搜索,方法是弹出最后一个元素及其父元素,如果它有子元素,则再次添加已访问的节点。 标志 防止再次添加它。这种方法访问节点两次,一次用于搜索最深度节点,另一次用于更新 size 属性。

const
    update = object => {
        const
            stack = [[object]];

        while (stack.length) {
            const [o, p, flag] = stack.pop();
           
            if (!flag && o.children) {
                stack.push([o, p, true]);
                Object.values(o.children).forEach(q => stack.push([q, o]));
            } else if (p) p.size += o.size;
        }
    },
    obj = { src: { size: 0, children: { api: { size: 0, children: { api_2: { size: 0, children: { 'file1.js': { size: 2 }, 'file2.js': { size: 2 } } }, api_1: { size: 0, children: { 'test1.js': { size: 1 }, 'test2.js': { size: 1 } } } } } } } };

update(obj.src);

console.log(obj.src.size); // 6
console.log(obj.src.children.api.size); // 6
console.log(obj.src.children.api.children.api_1.size); // 4
console.log(obj.src.children.api.children.api_2.size); // 2

console.log(obj.src);
.as-console-wrapper { max-height: 100% !important; top: 0; }

关于javascript - 将具有本地状态的递归函数转换为使用堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70730919/

相关文章:

algorithm - 递归函数的运行时

python - 如何将孙子添加到 python 树?

java - 在java中使用stacks(LinkedList)实现表达式树如下,但有错误

c++ - 后缀范围 c++

javascript - 距离 map 中心太远时 Mapbox 标记消​​失

javascript - PhpStorm调试器: How to ignore webpack dev server served script (node_modules)

javascript - 这个函数如何在没有循环的情况下处理数组?

data-structures - 使用二叉搜索树的有序映射的实用性

javascript - iPad 上的 jQuery Selectric 错误

javascript - TS : Infer literal typing based on chained methods