008广度优先搜索查找连通图中的最短路径

本文介绍如何使用广度优先搜索(BFS)算法在连通图中找到从起点到其它各点的最短路径。通过队列实现,确保每次访问的顶点到起点的路径都是最短的。代码实现包括标记已访问顶点和记录路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

图学习笔记索引

图学习笔记索引(全部)
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的​所有顶点。从队列的存取操作是按照顶点到起始顶点的距离(边的数量)进行的,可保证每个顶点到起始顶点的路径是该顶点到​起始顶点的最短路径。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值