当前位置: 首页 > news >正文

深度优先搜索(DFS)与广度优先搜索(BFS)全面解析 + 经典算法题实战(Java实现)

一、基本概念

DFS(Depth First Search)深度优先搜索

  • 思想:沿着一条路径不断深入,直到无法继续,再回溯到上一个节点,尝试其他路径
  • 实现方式:递归或显式栈
  • 特点
    • 先深入,再回退
    • 适用于需要穷尽所有路径或组合的场景

BFS(Breadth First Search)广度优先搜索

  • 思想:从起点出发,先访问所有邻居节点,再依次访问邻居的邻居
  • 实现方式:队列(Queue)
  • 特点
    • 分层遍历
    • 通常用于寻找最短路径

二、DFS 与 BFS 对比

特性DFSBFS
数据结构栈(递归调用栈或显式栈)队列(Queue)
遍历方式深度优先,先走到最深再回退广度优先,逐层扩展
时间复杂度O(V+E)O(V+E)
空间复杂度O(h),h 为递归深度O(w),w 为最宽层的节点数
路径特性不保证最短路径能找到最短路径(无权图)
应用场景全排列、连通块、拓扑排序等最短路径、层次遍历、最小步数等

三、可视化对比示例

以图为例(起点A):

     A
    / \
   B   C
  / \   \
 D   E   F
  • DFS 遍历顺序:A → B → D → E → C → F
  • BFS 遍历顺序:A → B → C → D → E → F

四、经典算法题示例

示例1:相同的树(LeetCode 100)

题目描述:

给你两棵二叉树的根节点 pq ,编写一个函数来检验这两棵树是否相同。

如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的

示例 1:

img

输入:p = [1,2,3], q = [1,2,3]
输出:true

示例 2:

在这里插入图片描述

输入:p = [1,2], q = [1,null,2]
输出:false

示例 3:

img

输入:p = [1,2,1], q = [1,1,2]
输出:false

提示:

  • 两棵树上的节点数目都在范围 [0, 100]
  • -104 <= Node.val <= 104
Java代码(DFS实现):
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */

public class Solution {
	public boolean isSameTree(TreeNode p, TreeNode q) {
        if (p == null && q == null) {
            return true;
        }
        
        if (p == null || q == null) {
            return false;
        }
        
        if(p.val != q.val) {
            return false;
        }
        
        return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
    }
}

递归法

  • 终止条件:两节点均为空时返回true;一个为空另一个非空时返回false
  • 值比较:当前节点值不同则直接返回false
  • 递归子问题:分别比较左子树和右子树是否相同,必须全部相同才返回true
Java代码(BFS实现):
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode() {}
 *     TreeNode(int val) { this.val = val; }
 *     TreeNode(int val, TreeNode left, TreeNode right) {
 *         this.val = val;
 *         this.left = left;
 *         this.right = right;
 *     }
 * }
 */
 
 public class Solution {
	public boolean isSameTree(TreeNode p, TreeNode q) {
        Queue<TreeNode> queue = new LinkedList<>();
        queue.offer(p);
        queue.offer(q);
        
        while(!queue.isEmpty()) {
            TreeNode node1 = queue.poll();
            TreeNode node2 = queue.poll();
            
            if(node1 == null && node2 == null) {
                continue;
            }
            
            if(node1 == null || node2 == null) {
                return false;
            }
            
            if(node1.val != node2.val) {
                return false;
            }
            
            queue.offer(node1.left);
            queue.offer(node2.left);
            queue.offer(node1.right);
            queue.offer(node2.right);
        }
        
        return true;
    }
}

迭代法

  • 队列初始化:将两棵树的根节点成对加入队列
  • 循环处理:每次取出两个节点进行比较,若值不同或结构不一致则返回false
  • 子节点入队:将对应的左子节点和右子节点成对加入队列,确保后续比较正确

示例2:岛屿数量(DFS-LeetCode 200)

题目描述:

给定一个二维的地图,‘1’ 表示陆地,‘0’ 表示水域,计算岛屿数量(连通的1为一个岛屿)

示例 1:

输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1

示例 2:

输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3
Java代码(DFS实现):
public class Solution {
    public int numIslands(char[][] grid) {
        int count = 0;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == '1') {
                    dfs(grid, i, j);
                    count++;
                }
            }
        }
        return count;
    }

    private void dfs(char[][] grid, int i, int j) {
        if (i < 0 || j < 0 || i >= grid.length || j >= grid[0].length || grid[i][j] == '0') {
            return;
        }
        grid[i][j] = '0';
        dfs(grid, i + 1, j);
        dfs(grid, i - 1, j);
        dfs(grid, i, j + 1);
        dfs(grid, i, j - 1);
    }
}

示例3:迷宫最短路径(BFS)

题目描述:

从起点走到终点,每次可以上下左右移动一步,求最短步数

Java代码(BFS实现):
import java.util.LinkedList;
import java.util.Queue;

public class MazeShortestPathBFS {
    public int shortestPath(int[][] maze, int[] start, int[] end) {
        int rows = maze.length, cols = maze[0].length;
        int[][] dirs = {{1,0},{-1,0},{0,1},{0,-1}};
        boolean[][] visited = new boolean[rows][cols];
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{start[0], start[1], 0});
        visited[start[0]][start[1]] = true;

        while (!queue.isEmpty()) {
            int[] cur = queue.poll();
            if (cur[0] == end[0] && cur[1] == end[1]) {
                return cur[2];
            }
            for (int[] dir : dirs) {
                int x = cur[0] + dir[0], y = cur[1] + dir[1];
                if (x >= 0 && y >= 0 && x < rows && y < cols && maze[x][y] == 0 && !visited[x][y]) {
                    visited[x][y] = true;
                    queue.offer(new int[]{x, y, cur[2] + 1});
                }
            }
        }
        return -1; // 无法到达终点
    }
}

五、应用场景总结

应用方向推荐算法
树的遍历DFS
寻找最短路径BFS
迷宫走法BFS
连通区域统计DFS
图中的路径查找DFS/BFS
组合/排列/搜索树DFS
http://www.dtcms.com/a/79836.html

相关文章:

  • leetcode106 从中序与后序遍历序列构造二叉树
  • Java学习笔记-XXH3哈希算法
  • Dify 项目开源大模型应用开发平台
  • deque
  • Linux基础开发工具--gdb的使用
  • 蓝桥杯青少组stema2025年3月9日scratch初级组真题——转动的图形
  • 除自身以外数组的乘积——面试经典150题(力扣)
  • 每天一道算法题-两数相加
  • C++编程语言特性
  • Android Jetpack Compose介绍
  • 238.除自身以外数组的乘积
  • 【sgHelp】自定义组件:网站、平台右下角的帮助助手、指导助理
  • app测试必须进行吗?需要进行哪些测试?
  • 混元视频与万相2.1全面对比分析
  • 嵌入式笔记 | 正点原子STM32F103ZET6 4 | 中断补充
  • 搭建个人博客教程(Hexo)
  • Django+celery+flower
  • 【文件分类助手V1.0b】支持自定义后缀分类整理及目录文档自动生成,方便大家美化管理自己的PC文件库支持Win10/11
  • 【从零开始学习计算机科学与技术】计算机网络(三)数据链路层
  • 蓝桥杯备考---》分类讨论之Fixed Points
  • 在Ubuntu20.04上交叉编译能在Windows上运行的Qt5应用
  • Vue3 集成wangEditor 5
  • 鸿蒙开发真机调试:无线调试和USB调试
  • MQ,RabbitMQ,MQ的好处,RabbitMQ的原理和核心组件,工作模式
  • LeetCode 解题思路 22(Hot 100)
  • 9.嗅探与Wireshark进阶分析
  • 使用Python在Word中创建、读取和删除列表 - 详解
  • DeepSeek接入多模态,个人电脑也能飞速生成高清图,确实可以封神了!
  • 目前主要虚拟世界平台在单一实例承载人数和伺服器架构的综合比较分析(从开资料和技术推估):
  • 寄存器(内部访问)