图 —— 广度优先搜索算法(BFS)

算法是作用于具体数据结构之上的,深度优先搜索算法和广度优先搜索算法都是基于“图”这种数据结构的。

图上的搜索算法,最直接的理解就是,在图中找出从一个顶点出发,到另一个顶点的路径。

而深度和广度优先搜索就是图的众多搜索算法中最简单的,也是最“暴力”的搜索算法

代码实现

前提

代码中的图结构是利用邻链表实现的无权无向图。

import java.util.LinkedList;
import java.util.Queue;

public class Graph {  //无向图

    private int v; // 顶点的个数
    private LinkedList<Integer> adj[]; // 邻接表

    public Graph(int v) {
        this.v = v;
        adj = new LinkedList[v];
        for (int i = 0; i < v; ++i) {
            adj[i] = new LinkedList<>();
        }
    }

    public void addEdge(int s, int t) { // 无向图一条边存两次
        adj[s].add(t);
        adj[t].add(s);
    }

    public void bfs(int s, int t) {
        if (s == t) return;
        boolean[] visited = new boolean[v]; //记录顶点是否被访问过,若被访问过则为true
        visited[s]=true;
        Queue<Integer> queue = new LinkedList<>(); //存储已经被访问、但相连的顶点还没有被访问的顶点。
        queue.add(s);
        int[] prev = new int[v]; //记录搜索路径,反向存储,prev[w]存储的是,顶点 w 是从哪个前驱顶点遍历过来的。
        for (int i = 0; i < v; ++i) {
            prev[i] = -1;
        }
        while (queue.size() != 0) { //一次循环将队列的队头顶点出队列
            int w = queue.poll();
            for (int i = 0; i < adj[w].size(); ++i) { //一次循环将已出队顶点相连的一个没有被访问过的节点入队列
                int q = adj[w].get(i);
                if (!visited[q]) { //若顶点没有被访问过,则记录下来顶点是从哪个前驱顶点遍历而来
                    prev[q] = w;
                    if (q == t) {  //若已搜索到目的顶点,则打印输出路径
                        print(prev, s, t);
                        return;
                    }
                    visited[q] = true;
                    queue.add(q); //将顶点设为已访问状态,并且入队
                }
            }
        }
    }

    private void print(int[] prev, int s, int t) { // 因为搜索路径是反向存储,递归打印s->t的路径
        if (prev[t] != -1 && t != s) {
            print(prev, s, prev[t]);
        }
        System.out.print(t + " ");
    }

    public static void main(String[] args) {
        Graph graph = new Graph(8);
        graph.addEdge(0,1);
        graph.addEdge(0,3);
        graph.addEdge(1,2);
        graph.addEdge(1,4);
        graph.addEdge(3,4);
        graph.addEdge(2,5);
        graph.addEdge(4,5);
        graph.addEdge(4,6);
        graph.addEdge(5,7);
        graph.addEdge(6,7);

//        Graph graph = new Graph(6);
//        graph.addEdge(0,1);
//        graph.addEdge(0,2);
//        graph.addEdge(1,3);
//        graph.addEdge(2,3);
//        graph.addEdge(3,4);
//        graph.addEdge(4,5);
//        graph.bfs(0,5);

    }
}
发布了113 篇原创文章 · 获赞 25 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_42006733/article/details/105068990