JAVA基于有权邻接表的Dijkstra迪杰斯特拉算法实现

本文深入探讨了基于有权邻接表的Dijkstra算法实现,详细介绍了算法的步骤,包括初始化距离、寻找最短路径、松弛操作等关键过程。通过具体实例展示了如何计算两点之间的最短路径,并提供了完整的代码实现。
这个参考了别人代码的基于有权邻接表的Dijkstra实现。
里面用到的图是基于上一篇文章里的图。
https://blog.youkuaiyun.com/weixin_41988248/article/details/89466903


public class Dijkstra {
    //图
    public Graph gh;
    //未求出最短路径的点集合
    public ArrayList<Integer> unVisited=new ArrayList();//使用Integer的泛型是因为可以直接通过Remove去掉元素
    //已求出最短路径的点集合
    public ArrayList hasVisited=new ArrayList();
    //记录从起点到其他任意一点的路径长度
    public Double distances[];
    //记录Path[i]表示从S到i的最短路径中,结点i之前的结点的编号,即对应点的前一个节点
    public int paths[];

    /**
     * 初始化各点距离及路径
     */
    public void init(int x,int y){
        distances=new Double[gh.vertexNum];
        paths=new int[gh.vertexNum];
        for(int i=0;i<distances.length;i++){
            distances[i]=Double.MAX_VALUE;
        }
        distances[x]=0.0;
        //把与x相邻的点的距离求出,并标准初始路径
        for(Edge edge=gh.adjList[x].firstedge;edge!=null;edge=edge.next){
            distances[edge.adjvertex]=edge.value;
            paths[edge.adjvertex]=x;
        }
        //初始化未知最短路点集合和已知最短路集合
        unVisited.clear();
        hasVisited.clear();
        hasVisited.add(x);
        //其余点为未知
        for(int i=0;i<gh.adjList.length;i++){
            if(i!=x){
                unVisited.add(i);
            }
        }
    }

    /**
     * Dijkstra路径计算算法
     * @param x 初始点(number)
     * @param y 目的点
     */
    public void Dijkstra_cal(int x,int y){
        init(x,y);

        while(!unVisited.isEmpty()){
            //求出距离x最短的点
            int number=pickMinInUnvisited(x);
            if(number==-1){
                break;
            }
            //将该点加入到hasvisited集合中,并从未访问集合中去掉
            hasVisited.add(number);
            unVisited.remove((Integer)number);
            //对该点(u)为起点,相邻的点为终点的临接点进行松弛操作,更新其他点的当前最短路径
            relax(number);
        }

        for(int i=0;i<distances.length;i++){
            System.out.println(x+"-->"+i+"距离为"+distances[i]);
        }

        ArrayList path=getPath(x,y);
        System.out.println("路程是"+path.toString());

    }

    /**
     * 从未求出最短路径的集合中找到与原点最近的点
     * @param x
     * @return
     */
    public int pickMinInUnvisited(int x){
        int minIndex=-1;
        Double min=Double.MAX_VALUE;
        for(int i=0;i<distances.length;i++){
            if(unVisited.contains(i)){
                if(distances[i]<min){
                    minIndex=i;
                    min=distances[i];
                }
            }
        }
        return minIndex;
    }

    /**
     * 对该点(u)为起点,相邻的点为终点的临接点进行松弛操作,更新其他点的当前最短路径
     * @param u
     */
    public void relax(int u){
        for(Edge edge=gh.adjList[u].firstedge;edge!=null;edge=edge.next){
            int v=edge.adjvertex;
            //看是否满足distances[v]>distances[u]+w[u][v]
            Double value=edge.value;
            if(distances[v]>distances[u]+value){
                distances[v]=distances[u]+value;
                //记录v的最短路径是,前一个节点为u
                paths[v]=u;
            }
        }

    }

    /**
     * 获取正向的路径信息
     * @param x
     * @param y
     * @return
     */
    public ArrayList getPath(int x,int y){
        ArrayList path=new ArrayList();
        while(y!=x){
            path.add(y);
            y=paths[y];
        }
        path.add(x);
        //路径倒置,需要反置回来
        Collections.reverse(path);
        return path;
    }



    public Dijkstra(Graph gh) {
        this.gh = gh;
    }

    public Dijkstra(){

    }


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值