问题的描述是这样的:有一个有向无权图G,指定一个特定的顶点s作为起点,要求找出从s出发到G中的每一个其它顶点的最短路径。如下面的这个图:
(用v1、v2、……作为每个顶点的名称吧。。。)
对于顶点类Vertex要存有两个信息,dist用来保存从s到此顶点的距离,path用来保存最短路径中的前一个顶点。比如说若此顶点是v7,开始顶点是v1,最短路径是v1-v3-v5-v7,那么path=v5。
以下的代码参考自 数据结构与算法分析——Java语言描述 (美)Mark Allen Weis 一书的附录
Vertex.java:
package com.noweight;
import java.util.LinkedList;
public class Vertex {
String name; //顶点名称
LinkedList<Vertex> adj; //相邻顶点
int dist; //距离
Vertex path; // 最短路径中的前一个顶点
public Vertex(String nm){
name=nm;
adj=new LinkedList<Vertex>();
reset();
}
public void reset(){
dist=Graph.INFINITY;
path=null;
}
}
Graph.java:
package com.noweight;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NoSuchElementException;
public class Graph {
public static final int INFINITY=Integer.MAX_VALUE;
private HashMap<String,Vertex> vertexMap=new HashMap<String,Vertex>();
//让vertexMap取得对Vertex对象的引用
private Vertex getVertex(String vertexName){
Vertex v=vertexMap.get(vertexName);
if(v==null)
{
v=new Vertex(vertexName);
vertexMap.put(vertexName,v);
}
return v;
}
//将距离初始化
private void clearAll(){
for(Iterator< Vertex> itr=vertexMap.values().iterator();itr.hasNext();)
{
itr.next().reset();
}
}
//显示实际最短路径
private void printPath(Vertex dest){
if(dest.path!=null)
{
printPath(dest.path);
System.out.print(" to ");
}
System.out.print(dest.name);
}
//添加一条新的边
public void addEdge(String sourceName,String destName){
Vertex v=getVertex(sourceName);
Vertex w=getVertex(destName);
v.adj.add(w);
}
//显示一条路径
public void printPath(String destName) throws NoSuchElementException{
System.out.print("To "+destName+": ");
Vertex w=vertexMap.get(destName);
if(w==null)
throw new NoSuchElementException("Destination vertex not found!");
else if(w.dist==INFINITY)
System.out.println(destName+" id unreachable!");
else {
printPath(w);
System.out.println();
}
}
//无权最短路径计算
public void unweighted(String startName){
clearAll();
Vertex start=vertexMap.get(startName);
if(start==null)
throw new NoSuchElementException("Start vertex not found!");
LinkedList<Vertex> q=new LinkedList<Vertex>();
q.addLast(start);
start.dist=0;
while(!q.isEmpty())
{
Vertex v=q.removeFirst();
for(Iterator<Vertex> itr=v.adj.iterator();itr.hasNext();)
{
Vertex w=itr.next();
if(w.dist==INFINITY)
{
w.dist=v.dist+1;
w.path=v;
q.addLast(w);
}
}
}
}
}
Main.java:
package com.noweight;
public class Main {
public static void main(String[] args) {
//构建图
Graph graph=new Graph();
graph.addEdge("v1", "v2");
graph.addEdge("v1", "v4");
graph.addEdge("v2", "v4");
graph.addEdge("v2", "v5");
graph.addEdge("v3", "v1");
graph.addEdge("v3", "v6");
graph.addEdge("v4", "v3");
graph.addEdge("v4", "v5");
graph.addEdge("v4", "v6");
graph.addEdge("v4", "v7");
graph.addEdge("v5", "v7");
graph.addEdge("v7", "v6");
//以v3为起点计算无权图的最短路径
graph.unweighted("v3");
//打印从v3到各个顶点的最短路径
System.out.println("The shortest path from v3:");
for(int i=1;i<=7;i++){
graph.printPath("v"+i);
}
}
}
运行的结果:
The shortest path from v3:
To v1: v3 to v1
To v2: v3 to v1 to v2
To v3: v3
To v4: v3 to v1 to v4
To v5: v3 to v1 to v2 to v5
To v6: v3 to v6
To v7: v3 to v1 to v4 to v7