广度优先搜索查找连通图中的最短路径
图学习笔记索引
图学习笔记索引(全部)
001自定义输入流In类实现
002背包数据类型Bag实现
003无向图数据类型实现
004基于图的深度优先搜索
005使用深度优先搜索找图中的所有连通分量
005-1基于深度优先搜索查找图中连通路径
006基于深度优先搜索判断图中是否存在环
007基于深度优先搜索判断一个无向图图是否是一个二分图
008广度优先搜索查找连通图中的最短路径
009有向图数据类型实现
010有向图的可达性
011带权重的无向边数据类型Edge实现
012加权无向图数据类型实现
本文参考《算法(第4版)》
广度优先搜索查找连通图中的最短路径
1.实现代码
流读取,图的构造参考:
https://blog.csdn.net/m0_37692918/article/details/102742999
图输入文件tinyCG.txt 信息:
6
8
0 5
2 4
2 3
1 2
0 1
3 4
3 5
0 2
package algorithms.graph;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
/*
* 使用广度优先搜索找连通图中的最短路径
* */
public class BreadthFirstPaths {
private boolean[] marked; //(从起点)到达该顶点的最短路径是否已知? 即marked[v],是否有从v到起点的最短路径
//edgeTo[]用于存储最短路径树,下一个顶点索引上一个顶点
private int[] edgeTo; //到达该顶点的已知路径上的最后一个顶点。
private final int s; //起点
BreadthFirstPaths(Graph G, int s){
this.marked = new boolean[G.V()];
this.edgeTo = new int[G.V()];
this.s = s;
bfs(G, s);
}
public void bfs(Graph G, int s) {
Queue<Integer> queue = new LinkedList<Integer>();
queue.add(s);
marked[s] = true;
while(!queue.isEmpty()){
int v = queue.remove();
for(int w : G.adj(v))
if(!marked[w]){
edgeTo[w] = v;
marked[v] = true;
queue.add(w);
}
}
}
public boolean hasPathTo(int v){
return marked[v];
}
public Stack<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;
}
// 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;
// }
//最短路径打印封装成方法
public void printPathFrom(Graph G, int s){
Stack<Integer> stack = new Stack<Integer>();
for(int v = 0; v < G.V(); v++){
stack = pathTo(v);
System.out.print(s + " to " + v + " shortest path is: ");
while(stack != null &&! stack.isEmpty()){
int w = stack.pop();
if(w == s) System.out.print(s);
else System.out.print("-" + w);
}
System.out.println();
}
}
public static void main(String[] args) throws IOException {
In in = new In("D:\\tinyCG.txt");
Graph G = new Graph(in);//G要求是连通图
System.out.println(G);
int s = 3;
BreadthFirstPaths search = new BreadthFirstPaths(G, s);
Stack<Integer> stack = new Stack<Integer>();
for(int v = 0; v < G.V(); v++){
stack = search.pathTo(v);
System.out.print(s + " to " + v + " shortest path is: ");
while(stack != null &&! stack.isEmpty()){
int w = stack.pop();
if(w == s) System.out.print(s);
else System.out.print("-" + w);
}
System.out.println();
}
//search.printPathFrom(G, s);
}
}
输出
2.总结
基于广度优先搜索查找连通图中的最短路径,使用一个队列queue依次存取每次遍历过程中距离起始顶点距离(边的数量)为1,2,3,4,…,k的所有顶点。从队列的存取操作是按照顶点到起始顶点的距离(边的数量)进行的,可保证每个顶点到起始顶点的路径是该顶点到起始顶点的最短路径。