图的遍历之DFS与BFS

图的遍历

图的遍历指的是从图中的任一顶点出发,对图中的所有顶点访问一次且只访问一次。图的遍历操作和树的遍历操作功能相似。图的遍历是图的一种基本操作,图的许多其它操作都是建立在遍历操作的基础之上。
根据访问节点的顺序,我们可以分成两种方法来对图进行遍历。分别是深度优先遍历(DFS)广度优先遍历(BFS)

DFS

算法思想:

从某个点一直往深处走,走到不能往下走之后,就回退到上一步,直到找到解或把所有点走完。

算法步骤(递归或栈实现)
  1. 访问指定起始地点。
  2. 若当前访问顶点的邻接顶点有未被访问的顶点,就任选一个访问。如果没有就回退到最近访问的顶点,直到与起始顶点相通的所有点被遍历完。
  3. 若途中还有顶点未被访问,则再选一个点作为起始顶点。重复步骤2(针对非连通图)。
算法实现
import java.util.Stack;

public class Demo_01_DFS {
    //递归版DFS
    public static void DFSbyRecursion(int[][] graph){
        int length = graph.length;
        boolean[] visited = new boolean[length];
        //为了预防图不是连通图的情况,若图为连通图则直接调用DFS,不需要for循环
        for (int i = 0; i < length; i++) {
            if(!visited[i])
                DFS(graph,i,visited);
        }
    }

    public static void DFS(int[][] graph,int vertex,boolean[] visited){
        visited[vertex] = true;
        //遍历该点
        System.out.print(vertex + " ");
        int length = graph.length;
        for (int i = 0; i < length; i++) {
            //找出与vertex相邻的点,进行DFS。找到一个点就DFS,遍历到底了就进行回退(这里注意递归的过程,)
            if(!visited[i] && graph[vertex][i] == 1){
                DFS(graph,i,visited);
            }
        }
    }

    //用栈实现DFS
    public static void DFSbyStack(int[][] graph){
        Stack<Integer> stack = new Stack<>();
        int length = graph.length;
        //判断元素是否被遍历过
        boolean[] visited = new boolean[length];
        for (int i = 0; i < length; i++) {
            if(!visited[i]){
                stack.push(i);
                visited[i] = true;
                boolean hasNext;
                //遍历第一个点
                System.out.print( i+ " ");
                while(!stack.empty()){
                    //取出栈顶元素
                    int temp = stack.peek();
                    //设置变量来判断是否有新点入栈,没有就弹出栈顶元素,有的话进行下一次循环。
                    hasNext = false;
                    for (int j = 0; j < length; j++) {
                        //找出一个与栈顶元素有连接且没有被遍历的点放入stack中,并遍历该点
                        if(!visited[j] && graph[temp][j] == 1){
                            stack.push(j);
                            visited[j] = true;
                            hasNext = true;
                            //遍历该点
                            System.out.print(j + " ");
                            break;
                        }
                    }
                    //如果没有下一个元素则回溯,删除栈顶元素
                    if (!hasNext){
                        stack.pop();
                    }
                }
            }
        }

    }
    public static void main(String[] args) {
        int[][] graph = {
                { 0, 1, 1, 0, 0 },
                { 0, 0, 1, 0, 1 },
                { 0, 0, 0, 0, 0 },
                { 1, 1, 0, 0, 1 },
                { 0, 0, 1, 0, 0 }
        };
        DFSbyRecursion(graph);
        System.out.println();
        DFSbyStack(graph);
    }
}

BFS

算法思想

从某个点一直把其邻接点走完,然后任选一个邻接点把与之邻接的未被遍历的点走完,如此反复走完所有结点。类似于树的层序遍历。

算法步骤(用队列实现)
  1. 访问指定起始点。
  2. 访问当前顶点的邻接顶点有未被访问的顶点,并将之放入队列中。
  3. 删除队列的队首节点。访问当前队列的队首,重复步骤2。直到队列为空。
  4. 若若途中还有顶点未被访问,则再选一个点作为起始顶点。重复步骤2。(针对非连通图)。
算法实现
import java.util.LinkedList;
import java.util.Queue;

public class Demo_02_BFS {
    //用队列来实现BFS
    public static void BFSbyQueue(int[][] graph){
        Queue<Integer> queue = new LinkedList<>();
        int length = graph.length;
        boolean[] visited = new boolean[length];

        //为了预防图不是连通图的情况,若图为连通图则不需要for循环
        for (int i = 0; i < length; i++) {
            if(!visited[i]){
                queue.add(i);
                visited[i] = true;
                System.out.print(i + " ");
                while(queue.size() != 0){
                    int temp = queue.poll();
                    //遍历所有与temp相邻的点,依次加入队列中,并遍历他们
                    for (int j = 0; j < length; j++) {
                        if(!visited[j] && graph[temp][j] == 1){
                            queue.add(j);
                            visited[j] = true;
                            System.out.print(j + " ");
                        }
                    }
                }//while
            }
        }
    }

    public static void main(String[] args) {
        int[][] graph = {
                { 0, 1, 0, 1, 0 },
                { 0, 0, 1, 0, 1 },
                { 0, 0, 0, 0, 0 },
                { 1, 1, 0, 0, 1 },
                { 0, 0, 1, 0, 0 }
        };
        BFSbyQueue(graph);
    }
}

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/qq_36528734/article/details/83475059
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞