图搜索的两种写法,广度优先和深度优先

最近AI的爆发大家都疯了,也确实够疯,前几年谁能天天和AI聊天呢,特别它越来越智能,越来越理解你,你越来越离不开它,我很好奇将来它会不会有情绪,太可怕了,一旦有了这个就有了感情,那才是人类的噩梦

整理下图的理解吧

它是复杂的非线性结构;比如社交好友,都有以下一些维度

  • 顶点:图至少有一个顶点;如每个用户就是一个顶点
  • 边:两点确定一个边
  • 度:一个顶点包含多少条边
  • 无向图:没有方向,比如同学,是护卫同学
  • 有向图:有方向,比如父子关系
  • 无权图:不关注相互的关系有多强
  • 有权图:需关注关系有多强
    示例

认识下下面集中图

邻接矩阵

就是二维数组,A[i][j],有就是1,无就是0;缺点浪费空间

邻接表

单链表

图的搜索

有哪些核心用途呢,解决需要探索所有可能性的问题,尤其是路径存在性和连通性分析

首先是

广度优先搜索BFS

特点看下图,波纹式向外搜索

下面附上广度优先搜索的算法以及注释

java 复制代码
/**
 * 广度优先搜索 (Breadth-First Search, BFS) 算法的实现
 * 广度优先搜索算法是一种图形搜索算法,它从根节点开始,沿着树的宽度遍历树的节点,直到找到目标节点或遍历完所有节点为止。
 * 广度优先搜索算法的基本思想是:首先将根节点放入队列中,然后从队列中取出第一个节点,并标记为已访问,然后依次访问该节点的相邻节点,
 * 并将其相邻节点放入队列中,重复以上步骤,直到队列为空或找到目标节点为止。
 * 广度优先搜索算法的特点是:它可以有效地搜索最短路径,但效率较低。
 */
public class BFSDemo {
    /**
     * 图的邻接表表示(使用List<List<Integer>>存储)
     * 例如:graph.get(0) 表示节点0的所有邻居节点
     */
    private static List<List<Integer>> graph;

    public static void main(String[] args) {
        // 示例:构建一个包含4个节点的图
        int totalNodes = 6;
        graph = new ArrayList<>(totalNodes);
        // 初始化每个节点的邻接表
        for (int i = 0; i < totalNodes; i++) {
            graph.add(new ArrayList<>());
        }
        // 添加图的边(无向图)
        addEdge(0, 1);
        addEdge(0, 2);
        addEdge(1, 3);
        addEdge(2, 3);
        addEdge(2, 5);
        addEdge(3, 4);
        addEdge(5, 4);

        // 从节点0开始执行BFS
        bfs(0, totalNodes);  // 输出:0 1 2 3 5 4
    }

    /**
     * 广度优先搜索(BFS)核心实现
     *
     * @param startNode  起始遍历节点
     * @param totalNodes 图中总节点数
     */
    public static void bfs(int startNode, int totalNodes) {
        // 队列用于存储待访问节点
        Queue<Integer> queue = new LinkedList<>();
        // 标记已访问节点(避免重复访问)
        boolean[] visited = new boolean[totalNodes];
        // 初始化:起始节点入队并标记为已访问
        queue.offer(startNode);
        visited[startNode] = true;
        System.out.print("BFS遍历顺序: ");
        while (!queue.isEmpty()) {
            int currentNode = queue.poll();
            System.out.print(currentNode + " "); // 输出访问节点
            // 遍历当前节点的所有邻居
            for (int neighbor : graph.get(currentNode)) {
                if (!visited[neighbor]) {
                    visited[neighbor] = true;  // 标记为已访问
                    queue.offer(neighbor);     // 邻居节点入队
                }
            }
        }
    }

    /**
     * 添加无向图的边(双向)
     */
    private static void addEdge(int u, int v) {
        graph.get(u).add(v);  // u -> v
        graph.get(v).add(u);  // v -> u(如果是无向图)
    }
}

有向图啥的自己参考改一改哈

深度优先搜索DFS

接下来讲解一下这个,相当于一条道走到黑,怎么绕远怎么来

下面这段代码用了递归判断是否访问过的方法遍历所有同生共死的兄弟

java 复制代码
import java.util.ArrayList;
import java.util.List;
/**
 * 深度搜索优先遍历算法的实现
 * 原理:从某个节点开始,递归地遍历它的相邻节点,直到所有节点都被访问过。
 * 时间复杂度:O(V+E),其中V是节点数,E是边数。
 * 空间复杂度:O(V),其中V是节点数。
 */
public class DFSDemo {
    private static List<List<Integer>> graph;
    private static boolean[] visited;

    public static void main(String[] args) {
        int totalNodes = 6;
        graph = new ArrayList<>(totalNodes);
        visited = new boolean[totalNodes];

        for (int i = 0; i < totalNodes; i++) {
            graph.add(new ArrayList<>());
        }
        // 添加边
        addEdge(0, 1);
        addEdge(0, 2);
        addEdge(1, 3);
        addEdge(2, 3);
        addEdge(2, 5);
        addEdge(3, 4);
        addEdge(5, 4);

        System.out.print("DFS递归遍历顺序: ");
        dfsRecursive(0);  // 输出: 0 1 3 2 5 4 或类似(取决于邻接表顺序)
    }

    /**
     * 递归实现
     * 每取出一个点,就查这个点连接的点List取一个判断是否访问过,每访问过就继续递归查这个点下面连接的点,直到所有点都被访问过。
     */
    public static void dfsRecursive(int node) {
        System.out.print(node + " ");
        //标记已访问,下面判断使用
        visited[node] = true;
        for (int neighbor : graph.get(node)) {
            if (!visited[neighbor]) {
                //如果没被访问过,就递归实现
                dfsRecursive(neighbor);
            }
        }
    }

    private static void addEdge(int u, int v) {
        graph.get(u).add(v);
        graph.get(v).add(u);
    }
}

好了,两个经典的家伙介绍完毕,祝你好运

相关推荐
毅炼15 小时前
hot100打卡——day17
java·数据结构·算法·leetcode·深度优先
仰泳的熊猫21 小时前
题目1432:蓝桥杯2013年第四届真题-剪格子
数据结构·c++·算法·蓝桥杯·深度优先·图论
踩坑记录1 天前
leetcode hot100 104. 二叉树的最大深度 easy 递归dfs 层序遍历bfs
leetcode·深度优先·宽度优先
iAkuya2 天前
(leetcode)力扣100 57电话号码的字母组合(回溯)
算法·leetcode·深度优先
山峰哥2 天前
SQL优化全解析:从索引策略到查询性能飞跃
大数据·数据库·sql·编辑器·深度优先
踩坑记录2 天前
leetcode hot100 226. 翻转二叉树 easy 递归 层序遍历 BFS
算法·leetcode·宽度优先
踩坑记录2 天前
leetcode hot100 easy 101. 对称二叉树 递归 层序遍历 bfs
算法·leetcode·宽度优先
scx201310042 天前
20260129LCA总结
算法·深度优先·图论
木井巳3 天前
【递归算法】验证二叉搜索树
java·算法·leetcode·深度优先·剪枝
晚风_END3 天前
postgresql数据库|pgbouncer连接池压测和直连postgresql数据库压测对比
数据库·postgresql·oracle·性能优化·宽度优先