博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
无向图的最短路径算法JAVA实现(转)
阅读量:5887 次
发布时间:2019-06-19

本文共 6538 字,大约阅读时间需要 21 分钟。

一,问题描述

给出一个无向图,指定无向图中某个顶点作为源点。求出图中所有顶点到源点的最短路径。

无向图的最短路径其实是源点到该顶点的最少边的数目。

本文假设图的信息保存在文件中,通过读取文件来构造图。文件内容的格式参考。

 

二,算法实现思路

无向图的最短路径实现相对于带权的有向图最短路径实现要简单得多。

源点的最短路径距离为0,从源点开始,采用广度优先的顺序,首先将与源点邻接的顶点的路径求出,然后再依次求解图中其他顶点的最短路径。

由于顶点的最短路径的求解顺序 是一个 广度优先的顺序,因此需要一个辅助队列。初始时,将源点的最短路径距离设置为0,将源点入队列。

然后,在一个while循环中,从队列中弹出顶点,遍历该顶点的邻接点,若该邻接点的距离未被更新过(表示该邻接点未被访问过),更新邻接点的最短路径距离为 该顶点的距离加上1,并将所有的邻接点入队列。

 

三,最短路径算法的实现

感觉该算法的实现与 ,有向图的都非常的相似。他们都采用了广度的思想在里面。

广度优先的思想就是:处理完某个顶点后,去处理该顶点的所有邻接点,处理完它的邻接点后,再去处理更远(更外层)的顶点。

算法的代码如下:

1     /* 2      * 计算源点s到无向图中各个顶点的最短路径 3      * 需要一个队列来保存图中的顶点,初始时,源点入队列,然后以广度的形式向外扩散求解其他顶点的最短路径 4      */ 5     private void unweightedShortestPath(Vertex s){ 6         //初始化 7         Queue
queue = new LinkedList<>(); 8 s.dist = 0; 9 queue.offer(s);//将源点dist设置为0并入队列10 11 while(!queue.isEmpty()){12 Vertex v = queue.poll();13 for (Edge e : v.adjEdges) {//扫描v的邻接边(点)14 if(e.endVertex.dist == Integer.MAX_VALUE){//如果这个顶点(e.endVertex)未被访问(每个顶点只会入队列一次)15 e.endVertex.dist = v.dist + 1;//更新该顶点到源点的距离16 queue.offer(e.endVertex);17 e.endVertex.preNode = v;//设置该顶点的前驱顶点18 }//end if19 }//end for20 }//end while21 }

第11行while循环,每个顶点出队列一次,第13行for循环,表示每条边被处理一次,故算法的时间复杂度为O(V+E)

第14行if语句表明,图中每个顶点只会入队列一次。因为,顶点入队列后,该顶点的 dist 设置为 v.dist+1,不再是 Integer.MAX_VALUE

 

四,完整代码实现

NonDirectedGraph.java构造图并实现最短路径算法

1 import java.util.Collection;  2 import java.util.LinkedHashMap;  3 import java.util.LinkedList;  4 import java.util.List;  5 import java.util.Map;  6 import java.util.Queue;  7   8 /*  9  * 求解无向图的单源最短路径 10  */ 11 public class NonDirectedGraph { 12     private class Vertex{ 13         private String vertexLabel;//顶点标识 14         private List
adjEdges;//与该顶点邻接的边(点) 15 private int dist;//顶点距离 16 private Vertex preNode; 17 18 public Vertex(String vertexLabel) { 19 this.vertexLabel = vertexLabel; 20 adjEdges = new LinkedList<>(); 21 dist = Integer.MAX_VALUE; 22 preNode = null; 23 } 24 } 25 private class Edge{ 26 private Vertex endVertex; 27 public Edge(Vertex endVertex) { 28 this.endVertex = endVertex; 29 } 30 } 31 32 private Map
nonDirectedGraph; 33 private Vertex startVertex;//图的起始顶点 34 35 public NonDirectedGraph(String graphContent) { 36 nonDirectedGraph = new LinkedHashMap<>(); 37 buildGraph(graphContent); 38 } 39 40 private void buildGraph(String graphContent){ 41 String[] lines = graphContent.split("\n"); 42 43 String startNodeLabel, endNodeLabel; 44 Vertex startNode, endNode; 45 for(int i = 0; i < lines.length; i++){ 46 String[] nodesInfo = lines[i].split(","); 47 startNodeLabel = nodesInfo[1]; 48 endNodeLabel = nodesInfo[2]; 49 50 endNode = nonDirectedGraph.get(endNodeLabel); 51 if(endNode == null){ 52 endNode = new Vertex(endNodeLabel); 53 nonDirectedGraph.put(endNodeLabel, endNode); 54 } 55 56 startNode = nonDirectedGraph.get(startNodeLabel); 57 if(startNode == null){ 58 startNode = new Vertex(startNodeLabel); 59 nonDirectedGraph.put(startNodeLabel, startNode); 60 } 61 Edge e = new Edge(endNode); 62 //对于无向图而言,起点和终点都要添加边 63 endNode.adjEdges.add(e); 64 startNode.adjEdges.add(e); 65 } 66 startVertex = nonDirectedGraph.get(lines[0].split(",")[1]);//总是以文件中第一行第二列的那个标识顶点作为源点 67 } 68 69 public void unweightedShortestPath(){ 70 unweightedShortestPath(startVertex); 71 } 72 73 74 /* 75 * 计算源点s到无向图中各个顶点的最短路径 76 * 需要一个队列来保存图中的顶点,初始时,源点入队列,然后以广度的形式向外扩散求解其他顶点的最短路径 77 */ 78 private void unweightedShortestPath(Vertex s){ 79 //初始化 80 Queue
queue = new LinkedList<>(); 81 s.dist = 0; 82 queue.offer(s);//将源点dist设置为0并入队列 83 84 while(!queue.isEmpty()){ 85 Vertex v = queue.poll(); 86 for (Edge e : v.adjEdges) {//扫描v的邻接边(点) 87 if(e.endVertex.dist == Integer.MAX_VALUE){//如果这个顶点(e.endVertex)未被访问(每个顶点只会入队列一次) 88 e.endVertex.dist = v.dist + 1;//更新该顶点到源点的距离 89 queue.offer(e.endVertex); 90 e.endVertex.preNode = v;//设置该顶点的前驱顶点 91 }//end if 92 }//end for 93 }//end while 94 } 95 96 //打印图中所有顶点到源点的距离及路径 97 public void showDistance(){ 98 Collection
vertexs = nonDirectedGraph.values(); 99 for (Vertex vertex : vertexs) {100 System.out.print(vertex.vertexLabel + "<--");101 Vertex tmpPreNode = vertex.preNode;102 while(tmpPreNode != null){103 System.out.print(tmpPreNode.vertexLabel + "<--");104 tmpPreNode = tmpPreNode.preNode;105 }106 System.out.println("distance=" + vertex.dist);107 }108 }109 }

打印路径也可以使用递归来实现:

1     public void showDistanceRecursive(Vertex v){2         if(v.preNode != null){3             showDistanceRecursive(v.preNode);4         }5         System.out.print(v.vertexLabel + "  ");6     }

打印顶点 v 的路径,第三行 先打印 v 的前驱顶点的路径,然后再在第5行打印 v 。

第5行的打印输出语句在第三行的递归调用语句之后,故最里层的递归调用最先被打印出来,最里层的递归调用即源点,因为只有源点的 preNode == null。

当所有的里层递归调用返回后,最终执行到最外层的递归调用处,执行第5行打印 顶点 v 后,整个递归结束。

 

TestShortestPath.java是个测试类,用来测试结果。

1 public class TestShortestPath { 2     public static void main(String[] args) { 3         String graphFilePath; 4         if(args.length == 0) 5             graphFilePath = "F:\\xxx"; 6         else 7             graphFilePath = args[0]; 8          9         String graphContent = FileUtil.read(graphFilePath, null);10         NonDirectedGraph graph = new NonDirectedGraph(graphContent);11         graph.unweightedShortestPath();12         graph.showDistance();13     }14 }

 

FileUtil.java负责读取存储图信息的文件。

保存图的 文件内容如下:

0,0,1,4

1,0,2,7
2,0,3,3
3,1,2,3
4,1,4,2
5,3,4,3
6,2,5,2
7,4,5,2

 

测试输出结果如下:

源点标识是 0,

0 号顶点到 1 号顶点的最短距离为1,路径为:0-->1

0 号顶点到 5 号顶点的最短距离为2,路径为:0-->2-->5

.....

....

 

http://www.cnblogs.com/hapjin/p/5435724.html

 

转载于:https://www.cnblogs.com/softidea/p/5447544.html

你可能感兴趣的文章
selinux
查看>>
ci完整集成
查看>>
深度学习目标检测(object detection)系列(二) SPP-Net
查看>>
Python类、模块、包的概念及区别
查看>>
FreeMarker笔记 第四章 其它
查看>>
Oracle 11g 新特性简介(一)
查看>>
详解Oracle的几种分页查询语句
查看>>
从零部署RHEV3.3红帽虚拟化-2 (用kvm虚拟机安装RHEL6.4)
查看>>
Varnish 3.X详解
查看>>
javascript继承方式详解
查看>>
lnmp环境安装sh脚本
查看>>
大型管理类软件项目开发,为什么必须要有代码生成器的深切体会总结
查看>>
白话讲反射技术 --- 适合初学者入门引导
查看>>
css变形 transform
查看>>
Entity Framework 4 in Action读书笔记——第七章:持久化对象到数据库:使用SaveChanges持久化实体...
查看>>
Android安全讲座第八层 android应用的安装和卸载
查看>>
bootstrap-下拉菜单(菜单项状态)
查看>>
SQL Server中如何监控死锁(Deadlock)
查看>>
View State的知识
查看>>
Mysql压缩版forWindows安装与配置
查看>>