树
树是n个节点的集合,树有且仅有一个顶点,被称为根节点,从根开始定义,根为第一层,根的直接子节点为第二层,依此类推,树中节点的最大层数被称为树的深度或高度。
树的遍历
在对树进行遍历的时候,可以分为先序,中序和后序,按照遍历方式可分为深度优先遍历(DFS)和广度优先遍历(BFS),详细如图:
首先我们构造一个树结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const tree = [ { id: 1, children: [ { id: 2, children: [{ id: 3 }, { id: 4, children: [{ id: 5 }, { id: 6 }] }], }, ], }, { id: 7, children: [ { id: 8, children: [{ id: 9 }], }, ], }, ]
|
深度优先遍历
深度优先搜索(depth first search),从图中也可以看出来,是从根节点开始,沿树的深度进行搜索,尽可能深的搜索分支。当节点所在的边都已经搜多过,则回溯到上一个节点,再搜索其余的边。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| const depthSearchWithRecursive = (source) => { const result = [] const dfs = (data) => { data.forEach((element) => { result.push(element.id) if (element.children && element.children.length > 0) { dfs(element.children) } }) } dfs(source) return result }
const depthSearchWithoutRecursive = (source) => { const result = [] const stack = JSON.parse(JSON.stringify(source)) while (stack.length !== 0) { const node = stack.shift() result.push(node.id) const len = node.children && node.children.length for (let i = len - 1; i >= 0; i -= 1) { stack.unshift(node.children[i]) } } return result }
console.log(depthSearchWithRecursive(tree)) console.log(depthSearchWithoutRecursive(tree))
|
广度优先遍历
广度优先搜索(breadth first search),从图中也可以看出来,是从根节点开始,沿树的宽度进行搜索,如果所有节点都被访问,则算法中止。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| const breadthSearch = source => { const result = []; const queue = JSON.parse(JSON.stringify(source)); while (queue.length > 0) { const node = queue.shift(); result.push(node.id); const len = node.children && node.children.length; for (let i = 0; i < len; i += 1) { queue.push(node.children[i]); } } return result; };
console.log(breadthSearch(tree))
|