图_bfs&dfs

1.BFS广度优先遍历

1.1算法思路

1.准备工作: 创建一个visited数组,用来记录已进入队列的顶点;
           创建一个队列,用来存放每一层的顶点;初始化图G。

2.从图中的v0开始访问,将的visited[v0]数组的值设置为true,同时将v0入队。

3.只要队列不空,则重复如下操作:
    (1)队头顶点u出队。
    (2)依次检查u的所有邻接顶点w,若visited[w]的值为false,则访问w,并将visited[w]置为true,同时将w入队。

1.2代码

class BFS {
    //adj[]邻接矩阵: true代表有路
    public static int[] bfs(boolean[][] adj, int start) {
        int n = adj.length;
        int[] res = new int[n];
        int index = 0;
        boolean[] v = new boolean[n];//为true代表已经进过队列了
        Queue queue = new LinkedList<>();
        queue.add(start);
        v[start] = true;
        int i;
        while(!queue.isEmpty()) {
            i = queue.poll();
            res[index++] = i;
            for(int j = 0; j < n; j++) {
                if(adj[i][j] && !v[j]) {
                    queue.add(j);
                    v[j] = true;
                }
            }
        }
        return res;
    }
}

2.DFS深度优先遍历

2.1算法思路

1.图的深度优先遍历要一路走到黑, 不撞南墙不回头, 如果撞到南墙就要回溯
2.显然回溯, 需要一个栈
3.每来到一个点都要把它周围没有出栈过的点重新加入栈中, 注意这里是没有出栈过的点, 也就是说这个点虽然已经在栈里了, 但是由于这个点还没有出去, 那么也要重新压栈, 是为了防止如下情况
1572229415128.png
如果我们从0开始深度优先遍历, 0 -> 2 -> 3 -> 5 此时, 下一步应该走的节点是1而不是4, 
但是如果你要在0入栈的时候就把1设为true,  在5出栈的时候就不会重新把1入栈, 
那么下一个节点就会走向4, 但正确的路线应该是:
[0, 2, 3, 5, 1, 4]
    而不是
[0, 2, 3, 5, 4, 1]

2.2代码

public class DFS {
    public static int[] dfs(boolean[][] adj, int start) {
        int n = adj.length;
        int[] res = new int[n];
        int index = 0;
        //为true代表已经出队列了, 和宽度优先遍历不一样, 宽度优先遍历在进队列是设为true就可以了
        boolean[] v = new boolean[n];
        Stack stack = new Stack<>();
        stack.push(start);
        int i;
        while(!stack.isEmpty()) {
            i = stack.pop();
            if(v[i]) {
                continue;//说明已经出过栈了,这里必须continue
            }
            v[i] = true;
            res[index++] = i;
            for(int j = 0; j < n; j++) {
                if(adj[i][j] && !v[j]) {
                    stack.push(j);
                }
            }
        }
        return res;
    }
}
//递归版本
static int index = 0;
//dfs的递归代码
public static int[] dfs(boolean[][] adj, int start) {
    int n = adj.length;
    boolean[] visited = new boolean[n];
    int[] res = new int[n];
    process(adj, start, visited, res);
    return res;

}
public static void process(boolean[][] adj, int start, boolean[] v, int[] res) {
    v[start] = true;
    res[index++] = start;
    for(int j = 0; j < adj.length; j++) {
        if(adj[start][j] && !v[j]) {
            process(adj, j, v, res);
        }
    }
}

你可能感兴趣的:(图_bfs&dfs)