广度优先搜索

/**
 * Created by eminem on 16-12-7.
 */
//广度优先搜索
public class BreadthFirstPaths {
    //从起点到达该顶点的最短路径已知吗
    private boolean[] marked;

    //到达该顶点的已知路径上的最后一个顶点
    private int[] edgeTo;

    //起点
    private final int s;

    public BreadthFirstPaths(Graph G, int s) {
        int num = G.V();
        marked = new boolean[num];
        edgeTo = new int[num];
        this.s = s;
        dfs(G, s);
    }

    //这个方法不是递归的,显式地使用了一个队列
    private void dfs(Graph G, int s) {
        Queue<Integer> queue = new Queue<Integer>();
        marked[s] = true;
        //首先把起点压进队列
        queue.enqueue(s);
        //当队列不为空时(代表着还没有分析完整张图)一直执行while内的代码
        //这段代码把所有和起点相连的顶点所对应的marked位置都修改为true,
        //具体的修改过程是:首先修改直接和起点相连的顶点,然后修改和起点之间相隔一个顶点的顶点,
        //如果在修改过程中发现某顶点已经被修改过了那么直接略过,这个做法正确性的证明在p340页命题A里
        while (!queue.isEmpty()) {
            //当第一次执行下面这行时v其实就是起点s
            int v = queue.dequeue();
            //当第一次执行下面的代码时w们就是直接和起点s相连的那些顶点
            //第二次执行时w们就是和起点s相隔了一个顶点的顶点
            for (int w : G.adj(v)) {
                if (!marked[w]) {
                    edgeTo[w] = v;
                    marked[w] = true;
                    queue.enqueue(w);
                }
            }
        }
    }

    public boolean hasPathTo(int v) {
        return marked[v];
    }

    public Iterable<Integer> pathTo(int v){
        if(!hasPathTo(v)) return null;
        Stack<Integer> stack=new Stack<Integer>();
        for(int x=v;x!=s;x=edgeTo[x]){
            stack.push(x);
        }
        stack.push(s);
        return stack;
    }

}

猜你喜欢

转载自blog.csdn.net/u010742342/article/details/53510040
今日推荐