图(二)—— 一个有向无权图的最短路径算法

本文介绍了一种用于寻找有向无权图中从指定起点到所有其他顶点最短路径的算法实现。通过使用Java语言,文章详细展示了Vertex和Graph类的设计,并提供了完整的代码示例。

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

问题的描述是这样的:有一个有向无权图G,指定一个特定的顶点s作为起点,要求找出从s出发到G中的每一个其它顶点的最短路径。如下面的这个图:

        (用v1v2、……作为每个顶点的名称吧。。。)

        对于顶点类Vertex要存有两个信息,dist用来保存从s到此顶点的距离,path用来保存最短路径中的前一个顶点。比如说若此顶点是v7,开始顶点是v1,最短路径是v1-v3-v5-v7,那么path=v5

        以下的代码参考自 数据结构与算法分析——Java语言描述  (Mark Allen Weis 一书的附录

        Vertex.java:

[java]  view plain copy
  1. package com.noweight;  
  2.   
  3. import java.util.LinkedList;  
  4.   
  5. public class Vertex {  
  6.       
  7.     String name;   //顶点名称  
  8.     LinkedList<Vertex> adj;  //相邻顶点  
  9.     int dist;      //距离  
  10.     Vertex path;  // 最短路径中的前一个顶点  
  11.       
  12.     public Vertex(String nm){  
  13.         name=nm;  
  14.         adj=new LinkedList<Vertex>();  
  15.         reset();  
  16.     }  
  17.     public void reset(){  
  18.         dist=Graph.INFINITY;  
  19.         path=null;  
  20.     }  
  21.   
  22. }  


        Graph.java:

[java]  view plain copy
  1. package com.noweight;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Iterator;  
  5. import java.util.LinkedList;  
  6. import java.util.NoSuchElementException;  
  7.   
  8. public class Graph {  
  9.       
  10.     public static final int INFINITY=Integer.MAX_VALUE;  
  11.       
  12.     private HashMap<String,Vertex> vertexMap=new HashMap<String,Vertex>();  
  13.       
  14.     //让vertexMap取得对Vertex对象的引用  
  15.     private Vertex getVertex(String vertexName){  
  16.           
  17.        Vertex v=vertexMap.get(vertexName);  
  18.        if(v==null)  
  19.        {  
  20.            v=new Vertex(vertexName);  
  21.            vertexMap.put(vertexName,v);  
  22.        }  
  23.        return v;  
  24.     }  
  25.     //将距离初始化  
  26.     private void clearAll(){  
  27.         for(Iterator< Vertex> itr=vertexMap.values().iterator();itr.hasNext();)  
  28.         {  
  29.             itr.next().reset();  
  30.         }  
  31.     }  
  32.     //显示实际最短路径  
  33.     private void printPath(Vertex dest){  
  34.           
  35.         if(dest.path!=null)  
  36.         {  
  37.             printPath(dest.path);  
  38.             System.out.print(" to ");  
  39.         }  
  40.         System.out.print(dest.name);  
  41.     }  
  42.       
  43.     //添加一条新的边  
  44.     public void addEdge(String sourceName,String destName){  
  45.           
  46.         Vertex v=getVertex(sourceName);  
  47.         Vertex w=getVertex(destName);  
  48.         v.adj.add(w);  
  49.     }  
  50.     //显示一条路径  
  51.     public void printPath(String destName) throws NoSuchElementException{  
  52.           
  53.         System.out.print("To "+destName+": ");  
  54.         Vertex  w=vertexMap.get(destName);  
  55.           
  56.         if(w==null)  
  57.             throw new NoSuchElementException("Destination vertex not found!");  
  58.         else if(w.dist==INFINITY)  
  59.             System.out.println(destName+" id unreachable!");  
  60.         else {  
  61.             printPath(w);  
  62.             System.out.println();  
  63.         }  
  64.     }  
  65.       
  66.     //无权最短路径计算  
  67.     public void unweighted(String startName){  
  68.           
  69.         clearAll();  
  70.         Vertex start=vertexMap.get(startName);  
  71.         if(start==null)  
  72.             throw new NoSuchElementException("Start vertex not found!");  
  73.         LinkedList<Vertex> q=new LinkedList<Vertex>();  
  74.         q.addLast(start);  
  75.         start.dist=0;  
  76.           
  77.         while(!q.isEmpty())  
  78.         {  
  79.             Vertex v=q.removeFirst();  
  80.             for(Iterator<Vertex> itr=v.adj.iterator();itr.hasNext();)  
  81.             {  
  82.                 Vertex w=itr.next();  
  83.                 if(w.dist==INFINITY)  
  84.                 {  
  85.                     w.dist=v.dist+1;  
  86.                     w.path=v;  
  87.                     q.addLast(w);  
  88.                 }  
  89.                   
  90.             }  
  91.         }         
  92.     }  
  93. }  


        Main.java:

[java]  view plain copy
  1. package com.noweight;  
  2.   
  3. public class Main {  
  4.   
  5.       
  6.     public static void main(String[] args) {  
  7.           
  8.           //构建图  
  9.           Graph graph=new Graph();  
  10.           graph.addEdge("v1""v2");  
  11.           graph.addEdge("v1""v4");  
  12.           graph.addEdge("v2""v4");  
  13.           graph.addEdge("v2""v5");  
  14.           graph.addEdge("v3""v1");  
  15.           graph.addEdge("v3""v6");  
  16.           graph.addEdge("v4""v3");  
  17.           graph.addEdge("v4""v5");  
  18.           graph.addEdge("v4""v6");  
  19.           graph.addEdge("v4""v7");  
  20.           graph.addEdge("v5""v7");  
  21.           graph.addEdge("v7""v6");  
  22.             
  23.           //以v3为起点计算无权图的最短路径  
  24.           graph.unweighted("v3");  
  25.           //打印从v3到各个顶点的最短路径  
  26.           System.out.println("The shortest path from v3:");  
  27.           for(int i=1;i<=7;i++){  
  28.               graph.printPath("v"+i);  
  29.           }            
  30.     }  
  31. }  


        运行的结果:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值