算法—12.广度优先搜索

1.具体算法

/**
 * Created by huazhou on 2015/12/6.
 */
public class TestSearch {
    public static void main(String[] args){
        Graph G = new Graph(new In(args[0]));
        int s = Integer.parseInt(args[1]);
//        DepthFirstSearch search = new DepthFirstSearch(G, s);
//        Paths search = new Paths(G, s);
//        DepthFirstSearch search = new DepthFirstSearch(G,s);
        BreadthFirstPaths search = new BreadthFirstPaths(G,s);
        findAllPaths(search, G, s);
    }

    private static void findAllPaths(BreadthFirstPaths search, Graph G, int s){
        for(int v = 0; v < G.V(); v++){
            StdOut.print(s + " to " + v + ": ");
            if(search.hasPathTo(v)){
                for (int x : search.pathTo(v)){
                    if(x == s){
                        StdOut.print(x);
                    }
                    else{
                        StdOut.print("-" + x);
                    }
                }
            }
            StdOut.println();
        }
    }
}
/**
 * 算法4.2 使用广度优先搜索查找图中的路径
 * Created by huazhou on 2015/12/9.
 */
public class BreadthFirstPaths {
    private boolean[] marked;   //到达该顶点的最短路径已知吗?
    private int[] edgeTo;   //到达该顶点的已知路径上的最后一个顶点
    private int s;  //起点

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

    private void bfs(Graph G, int s){
        Queue<Integer> queue = new Queue<Integer>();
        marked[s] = true;   //标记起点
        queue.enqueue(s);   //将它加入队列
        while(!queue.isEmpty()){
            int v = queue.dequeue();    //从队列中删去下一顶点
            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> path = new Stack<Integer>();
        for (int x = v; x != s; x = edgeTo[x]){
            path.push(x);
        }
        path.push(s);
        return path;
    }
}

2.执行过程

3.算法分析

命题:对于从s可达的任意顶点v,广度优先搜索都能找到一条从s到v的最短路径(没有其他从s到v的路径所含的边比这条路径更少)

命题:广度优先搜索所需的时间在最坏情况下和V+E成正比。

 

源码下载

posted @ 2015-12-15 15:09  是非猫  阅读(508)  评论(0编辑  收藏  举报