前端问算法?聊聊DFS与BFS

526 阅读2分钟

是什么?

深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath First Search)是图论中两种非常重要的算法。

DFS
它的特点是不撞南墙不回头,先走完一条路,再换一条路继续走

  1. 从图中一个未访问的顶点 V 开始,沿着一条路一直走到底
  2. 从这条路尽头的节点回退到上一个节点,再从另一条路开始走到底...,
  3. 不断递归重复此过程,直到所有的顶点都遍历完成

imageonline-co-gifimage.gif

BFS
也叫层序遍历,

  1. 从图的一个未遍历的节点出发
  2. 先遍历这个节点的相邻节点
  3. 依次遍历每个相邻节点的相邻节点。

29dc30c1546cc73846153359b0fad8fb.gif

两种算法的现实应用

  • 拓扑排序
  • 寻路(走迷宫)
  • 搜索引擎
  • 爬虫
  • 面试

实现

数据结构

结构图

7baebe9f8daff26cc7d0cd7759be096b.png

数据表示

const treeObj = {
    value: 1,
    node: [
        {
            value: 2,
            node: [
                { value: 5, node: [{ value: 9, node: null }] },
            ],
        },
        {
            value: 3,
            node: [
                { value: 6, node: [{ value: 10, node: null }] },
                { value: 7, node: null },
            ],
        },
         {
            value: 4,
            node: [
                { value: 8, node: null },
            ],
        }
    ],
};

深度优先遍历DFS

  1. 如果有子节点则一直遍历子节点
  2. 递归,往深度一头扎进去

因此输出结果因该为:1, 2, 5, 9, 3, 6, 10, 7, 4, 8

function depthFirstSearch(target) {
    const result = [];
    const deal = data => {
        result.push(data.value);
        if (data.node) {
            data.node.forEach(item => deal(item));
        }
    };
    deal(target);
    return result;
}
console.log(depthFirstSearch(treeObj));

广度优先遍历BFS

  1. 使用队列
  2. 如果队列中有数据则继续循环
  3. 每次循环从队列中出队一项

因此输出结果因该为: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10


function breadthFirstSearch(target) {
   const result = [];
   const queue = [target];
   while(queue.length) {
       const item = queue.shift();
       result.push(item.value);
       if (item.node) {
           item.node.forEach(item => queue.push(item))
       }
   }
   
   return result;
}
console.log(breadthFirstSearch(treeObj));

leetcode练习

# 104. 二叉树的最大深度
# 102. 二叉树的层序遍历

参考

# 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)