无向图-不带权-文件读取-最短路径算法-JAVA实现

来源:互联网 发布:linux怎么装vnc 编辑:程序博客网 时间:2024/05/16 23:01
一 问题描述
1.无向图中某个顶点作为源点
2.求出图中所有顶点到源点的最短路径

二 算法实现思路
1.源点的最短路径距离为0,从源点开始,采用广度优先的顺序,首先将与源点邻接的顶点的路径求出,然后再依次求解图中其他顶点的最短路径。
2.由于顶点的最短路径的求解顺序 是一个 广度优先的顺序,因此需要一个辅助队列。初始时,将源点的最短路径距离设置为0,将源点入队列。
3.然后,在一个while循环中,从队列中弹出顶点,遍历该顶点的邻接点,若该邻接点的距离未被更新过(表示该邻接点未被访问过),更新邻接点的最短路径距离为 该顶点的距离加上1,并将所有的邻接点入队列。

三 最短路径算法的实现


四 代码
import java.io.File;import java.util.Collection;import java.util.LinkedHashMap;import java.util.LinkedList;import java.util.List;import java.util.Map;import java.util.Queue;public class NonDirectedGraph {public static void main(String[] args) {        String graphFilePath;        if(args.length == 0)            graphFilePath = "F:\\xxx";        else            graphFilePath = args[0];                String graphContent = FileUtil.read(graphFilePath, null);//文件读取        NonDirectedGraph graph = new NonDirectedGraph(graphContent);//构建        graph.unweightedShortestPath();//算法实现        graph.showDistance();//展示}//起始点——声明private Vertex startVertix;//图——数据结构——哈希映射(键值对)private Map<String, Vertex> nonDirectedGraph;//无向图——构造器public NonDirectedGraph(String graphContent) {nonDirectedGraph=new LinkedHashMap<>();//哈希映射buildGraph(graphContent);//构图}//构图——函数private void buildGraph(String graphContent) {String[] lines=graphContent.split("\n");//内容行数组String startNodeLabel, endNodeLabel;//开始点的标签,结束点的标签Vertex startNode, endNode;//开始结束点for(int i=0;i<lines.length;i++){String[] nodesInfo=lines[i].split(",");//每个顶点的信息startNodeLabel=nodesInfo[1];//读取顶点信息,并且设置开始点的标签endNodeLabel=nodesInfo[2];//同上//根据标签获取结束点endNode=nonDirectedGraph.get(endNodeLabel);//根据结束标签获得结束点if(endNode==null){//结束点不存在endNode=new Vertex(endNodeLabel);//新nonDirectedGraph.put(endNodeLabel,endNode);//放入无向图}//根据标签获取开始点startNode = nonDirectedGraph.get(startNodeLabel);if(startNode == null){ startNode = new Vertex(startNodeLabel); nonDirectedGraph.put(startNodeLabel, startNode);}//开始和结束点的边,对于无向图而言,起点和终点都要添加边Edge e=new Edge(endNode);endNode.adjEdge.add(e);startNode.adjEdge.add(e);}//以文件中第一行第二列的那个标识顶点作为源点startVertix=nonDirectedGraph.get(lines[0].split(",")[1]);}//顶点-定义private class Vertex{private String vertixLable="";//顶点是否已经访问的标志private List<Edge> adjEdge;//顶点的邻接边private int dist;//顶点距离上一顶点的距离private Vertex preVertex;//上一个顶点//构造函数public Vertex(String vertixLable) {this.vertixLable=vertixLable;//是否访问过adjEdge=new LinkedList<>();//邻边列表dist=Integer.MAX_VALUE;//距离初始化为最大值preVertex=null;//上一顶点初始为空}}//边-定义private class Edge{private Vertex endVeritx;//边的结束顶点public Edge(Vertex endVeritx) {this.endVeritx=endVeritx;}}//实现算法//无权最短路径,源点到无向图中各个顶点之间的最短路径//需要一个队列来保存图中的顶点,初始时,源点入队列,然后以广度的形式向外扩散求解其他顶点的最短路径private void unweightedShortestPath(Vertex s) {Queue<Vertex> queue=new LinkedList<>();//顶点队列s.dist=0;//源点距离初始为0queue.offer(s);//源点入队列while(!queue.isEmpty()){//队列非空Vertex v=queue.poll();//读取队列第一个元素for(Edge e:v.adjEdge){//v 顶点的每个顶点if(e.endVeritx.dist==Integer.MAX_VALUE){//如果这个顶点(e.endVertex)未被访问(每个顶点只会入队列一次)e.endVeritx.dist=v.dist+1;//更新距离,加一个顶点queue.offer(e.endVeritx);//结束顶点入队e.endVeritx.preVertex=v;//结束顶点的前一个顶点为V顶点}}}}    public void unweightedShortestPath(){        unweightedShortestPath(startVertix);    }//打印图中所有顶点到源点的距离及路径public void showDistance() {Collection<Vertex> vertexs=nonDirectedGraph.values();for(Vertex vertex:vertexs){System.out.print(vertex.vertixLable+"<——");Vertex tempPreNode=vertex.preVertex;while(tempPreNode!=null){System.out.print(tempPreNode.vertixLable+"<——");tempPreNode=tempPreNode.preVertex;}System.out.println("距离="+vertex.dist);}}}





0 0