欢迎使用CSDN-markdown编辑器

最短路径算法

基于广度优先的Dijkstra算法,本算法针对的问题如下:

  • 无向图
  • 不带权
  • 文件读取
  • 最短路径算法
  • JAVA实现
  • 离线写博客

一 问题描述
1.无向图中某个顶点作为源点
2.求出图中所有顶点到源点的最短路径

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

三 测试结果:
保存文件:
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

四:代码

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;//源点距离初始为0
        queue.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值