遍历树的几种方式: 递归遍历,非递归深度优先遍历,非递归广度优先遍历。
如上图,在 JavaScript 中可以用 object 表示如下:
let tree = {
value: 10,
children: [
{
value: 15,
children: [
{
value: 7,
children: []
},
{
value: 18,
children: []
}
]
},
{
value: 4,
children: []
},
{
value: 8,
children: [
{
value: 23,
children: []
}
]
}
]
};
递归遍历
const recursiveTraverse = function(node, action) {
if (!node || !node.children) {return;}
action(node.value);
node.children.forEach(function(item, index) {
recursiveTraverse(item, action)
})
}
recursiveTraverse(tree, console.info)
// 输出结果:
10
15
7
18
4
8
23
非递归深度优先遍历(借助栈实现)
const nonRecursiveDepthFirstTraversal = function (node, action) {
if (!node || !node.children) { return; }
let _stack = []; // 借助一个栈
_stack.unshift(node);
while (_stack.length) {
let _curNode = _stack.shift(); // 推出栈顶元素
action(_curNode.value);
// 将子节点依次放入到栈顶
// _curNode.children.forEach(function (item, index) {
// _stack.unshift(item);
// })
if (_curNode.children.length) {
_stack = _curNode.children.concat(_stack);
}
}
}
// 非递归深度优先遍历
nonRecursiveDepthFirstTraversal(tree, console.log);
// 输出结果:
10
15
7
18
4
8
23
非递归广度优先遍历(借助队列实现)
const nonRecursiveWidthFirstTraversal = function (node, action) {
if (!node || !node.children) { return; }
let _queue = []; // 借助一个队列
_queue.push(node);
while (_queue.length) {
let _curNode = _queue.shift(); // 推出队头元素
action(_curNode.value);
// 将子节点依次推入队列中
// _curNode.children.forEach(function (item, index) {
// _queue.push(item);
// })
if (_curNode.children.length) {
_queue = _queue.concat(_curNode.children);
}
}
}
// 非递归宽度优先遍历
nonRecursiveWidthFirstTraversal(tree, console.log);
// 输出结果:
10
15
4
8
7
18
23