4.2.1 单点最短路径
- 问题:给定一幅图和一个起点s,问从s到给定顶点v是否存在一条路径?如果有,找出其中最短的一条
 - 思路:要找到s到v的最短路径,从s开始,在所有的距离为1的点中找v,如果没有,则到距离为2的点中找v,如此反复
 
广度优先搜索(BFS)和深度优先搜索(DFS)
- DFS:选用递归(隐式栈),使用LIFO规则从有带搜索的通道中选择最晚遇到的那条往下走
 - BFS:按照与起点的距离顺序来遍历所有顶点,使用(FIFO)队列实现,从有带搜索的通道中选择最早遇到的那条
 
实现
public class BreadthFirstPaths {    private boolean[] marked;//是否之前已有更短路径到达    private int[] edgeTo;//到达该结点已知路径上的最后顶点    private final int s;    public BreadthFirstPaths(Graph G, int s){        marked = new boolean[G.V()];        edgeTo = new int[G.V()];        this.s = s;        bfs(G,s);    }    (队列)    public void bfs(Graph G, int s){        Queue<Integer> queue = new Queue<>();        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);//添加至队列                }            }        }    }    private boolean hasPathTo(int v){ return marked[v]; }    //返回s到v的最短路径    public Iterable<Integer> pathTo(int v){        if (!hasPathTo(v)) return null;        Stack<Integer> path = new Stack<>();        for (int i = v; i != s; i = edgeTo[i])            path.push(i);        path.push(v);        return path;    }}
- 虽然和DFS的pathTo()实现方法一样但BFS会给出s到v的一段最短路径
 
算法分析
- 对于从s可达的任意顶点v,BFS都可以找到一条从s到v的最短路径
 - BFS搜索时间在最坏情况下和V+E成正比
 
BFS和DFS对比
- 相同点:
- 搜索时都会先将起点存入数据结构中,然后重复一下操作指导数据结构被清空
- 取下一个顶点并标记
 - 将v的所有相邻而又未被标记的顶点继续加入数据结构
 
 
 - 不同点:
- DFS选取递归/隐式栈,每次将最晚一个加入的结点当作下一个顶点
 - BFS选取队列,每次将最早一个加入的结点当作下一个顶点