遍历树状数据结构最常用的两个算法就是:深度优先算法(Depth-First-Search,简称DFS)和广度优先算法(Breadth-First-Search,简称BFS)。我们以封面节点为例说明两种算法实现
深度优先算法
深度优先,顾名思义在遍历树节点时可能深的搜索树的分支
- 自上而下遍历最深的分支节点;
- 叶子节点再无子节点,回溯到父节点;
- 从左向右,遍历父节点的其他子节点,重复步骤1直到叶子节点,然后重复步骤2直至完成整个树的遍历;
按照封面的树结构依次遍历:1 => 2 => 3 => 4 => 5 => 6 => 7 => 8 => 9 => 10 => 11 => 12
深度优先算法遍历采用栈stack(first in last out)先进后出的思想实现:
递归循环
const depth1 = (dom, nodeList) => {
nodeList.push(dom.name)
dom.children.forEach((element) => {
depth1(element, nodeList)
})
}
const nodeList = []
depth1(Dom, nodeList)
console.log(nodeList.join('=>'))
栈思想
const depth2 = (node) => {
const stack = []
const nodes = []
if (node) {
stack.push(node)
while (stack.length) {
//从栈顶弹出一个节点
const item = stack.pop()
nodes.push(item.name)
while(item.children.length){
//如果当前节点有子节点,子节点倒序压入栈,即左边的节点压在上面,右边节点压在下面,出栈达到从左向右的效果
stack.push(item.children.pop())
}
}
}
return nodes.join('=>')
}
console.log(depth2(Dom));
广度优先算法
广度优先则是从上到下,自左向右层层遍历,即先遍历父节点,再遍历子节点。采用队列queue(fisrt in first out)先进先出的思想实现
const breadth = (dom) => {
const queue = []
const nodeList = []
if (dom) {
queue.push(dom)
while (queue.length) {
//从队列头部取出一个节点
const item = queue.shift()
nodeList.push(item.name)
//子节点依次从队列尾部加入
item.children.forEach((child) => {
queue.push(child)
})
}
}
return nodeList
}
const result = breadth(dom)
console.log(result.join('=>'))