JavaScript实现深度优先(DFS)和广度优先(BFS)算法

6,246 阅读1分钟

遍历树状数据结构最常用的两个算法就是:深度优先算法(Depth-First-Search,简称DFS)和广度优先算法(Breadth-First-Search,简称BFS)。我们以封面节点为例说明两种算法实现

深度优先算法

深度优先,顾名思义在遍历树节点时可能深的搜索树的分支

  1. 自上而下遍历最深的分支节点;
  2. 叶子节点再无子节点,回溯到父节点;
  3. 从左向右,遍历父节点的其他子节点,重复步骤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('=>'))