Skip to content
On this page

1. BFS/DFS区别

  1. BFS找到的路径一定是最短
  2. BFS的空间复杂度比DFS大很多

2. 如何判断是BFS

  • 在一个图中,找起点到终点的最短距离
    • 二叉树也可以理解为1个图

2. BFS步骤

重点是【当前队列】
概念:

  1. 当前队列:需要向外扩展的数据,
  2. 已访问列表:避免走回头路。(二叉树没有子到父的指针,一般不需要已访问列表)
  3. 扩散步数:记录距离(这个一般为答案)

步骤:

  1. 【起点】推入当前队列
  2. 当前队列的点向外扩散
  3. 判断是否抵达【终点】,抵达则返回扩散步数
    未抵达,则将当前点所有邻点推入当前队列
  4. 一轮扩散完毕后,扩散步数更新

3. BFS框架

js
function BFS(start, target) {
   var q = [] // 当前队列
   var visited = new Set() // 已访问列表

   q.push(start) // 起点加入当前队列
   visited.add(start)
   var step = 0 // 记录扩散步数

   while( q.length) {
      var length = q.length // 记录当前队列长度

      /* 当前队列中的所有节点向外扩散 */
      for (var i = 0; i < length; ++i) {
         var cur = q.shift() 

         /* 划重点,判断是否抵达终点 */
         if(cur === target) {
            return step
         }

         /* 将当前点所有邻点加入当前队列 */
         for(邻点 of 所有邻点) {
            if (visited.includes(邻点)) continue
            q.push(邻点)
            visited.add(邻点)
         }
      }
      /* 划重点,步数更新 */
      step++
   }
}

4. 细化问题点

4.1 时间复杂度低,O(N)

根据其框架逻辑,循环一次depth增加一次,找到终点时能保证距离最短。最坏情况下在满二叉树时,从根节点起点,找底层最后一个树节点时,就需要全部节点穷举过,所以是O(N) DFS也是O(N),但永远都是需要所有分叉都走完才能对比,实际比BFS慢很多。BFS是面,DFS是线。BFS是集体行动,DFS是单打独斗。

4.2 空间复杂度高,为O(N)

空间复杂度为O(N)。最坏情况下在满二叉树时,存了最底部的树节点N/2,所以最坏空间复杂度O(N)。而DFS是递归,是一条线,最坏情况下也是树的高度,即O(logN)

4.3 双向BFS-优化

从起点和终点同时扩散,相遇(有交集)时停止。最坏时还是O(N),但实际中,如果是起点根节点,满二叉树底部的中间终点,便只要遍历半棵树。

总结

  1. BFS与DFS
    • BFS的实际时间复杂度低,但空间复杂度高,而DFS相反。
    • 时间复杂度
      BFS: O(N)
      DFS: O(N)
    • 空间复杂度
      BFS: O(N)
      DFS: O(logN)

课后疑问s

参考资料