问题的描述是这样的:有一个有向无权图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