临时写了一个遍历树的方法,求改成尾递归。

2020-05-15 11:36:13 +08:00
 waiaan
  var traverseNode = function (node, i, arr, cb) {
    cb(node, i, arr);
    if (node.children) {
      var children = node.children;
      for (var i = 0; i < children.length; i++) {
        var childNode = children[i];
        traverseNode(childNode, i, children, cb)  // 如何改成尾递归的形式
      }
    }
  }

  var traverseTree = function (tree, cb) {
    for (var i = 0; i < tree.length; i++) {
      traverseNode(tree[i], i, tree, cb)
    }
  }

谢谢。

1498 次点击
所在节点    JavaScript
3 条回复
autoxbc
2020-05-15 21:04:23 +08:00
尾递归有这么几个要点:

1. 计算出中间结果,传递给下一次运算
2. 怎样得到下一次计算需要的数据
3. 递归终点

对于在结构数据上递归,第二条稍微复杂一些。数据不是一维的,那么需要设计一个无遗漏,最好也不重复的迭代规则

不确定你的函数怎么改写成尾递归,我只是写了一个简单的深度优先的节点遍历

function traverseNode( node , cb , top , back )
{
var top = top || node ;

if( back || node.children.length === 0 )
{
cb(node);
if( node === top )
return;

if(node.nextElementSibling)
return traverseNode( node.nextElementSibling , cb, top );

if(node.parentNode)
return traverseNode( node.parentNode , cb , top , true );
} else {
return traverseNode( node.children[0] , cb , top );
}
}

以及,对于节点这种特殊数据,有更好的方法可以一次获得所有子节点(包括自身)

[ node , node.querySelectorAll('*') ]
autoxbc
2020-05-15 21:13:45 +08:00
top 参数的意思是,当递归回自身时,表示已经处理所有节点,所以直接退出

back 参数的意思是,从子节点返回父节点时,告诉函数子节点已处理完毕
waiaan
2020-05-18 09:04:34 +08:00
@autoxbc 谢谢,我学习一下。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/671952

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX