算法->Dijkstra(迪杰斯特拉)算法介绍

210 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第22天,点击查看活动详情

Dijkstra(迪杰斯特拉)算法

用于计算一个节点到其他节点的最短路径。

基本原理

从起始点出发,重复寻找当前距离起始点最近的且未访问过的结点,然后利用该结点更新距离数组,直到访问过全部结点为止,最终的距离数组即为起始点到其余个点的最短路径距离。

算法的实现步骤

1.建一个数组d[n],表示从第n个节点到第1个节点的最短距离,然后初始化d[1]=1,其他的为正无穷。

2.遍历找到一个没有被覆盖的d[x]的最小的节点x,然后标记x

3.尝试x的每个出边(x,y,z),如果d[y]>d[x]+z,就赋值d[y]=d[x]+z;(z为x到y的距离);

4.最后重复以上过程,直到所有的点都被标记,就完事儿了

代码实现

    public static final int I = 100;
    int[][] array=new int[][]{
            {0,1,5,I,I,I,I,I,I},
            {1,0,3,7,5,I,I,I,I},
            {5,3,0,I,1,7,I,I,I},
            {I,7,I,0,2,I,3,I,I},
            {I,5,1,2,0,3,6,I,I},
            {I,I,7,I,3,0,I,5,I},
            {I,I,I,3,6,I,0,2,7},
            {I,I,I,I,9,5,2,0,4},
            {I,I,I,I,I,I,7,4,0}
    };
    public void dijkstar(){
        int k=0;//表示当前正要处理的顶点Vk

        //初始化相关的信息
        int[] path=new int[9];
        int[] weight=array[0];
        //定义一个数组来存放U和V两个集合的信息
        int[] flag=new int[9];
        flag[0]=1;
        //开始逻辑,求VO到某个顶点的最短路径
        for(int v=1;v<9;v++){
            //在能走的路径中找到最短的一条
            int min=I;
            for(int i=0;i<9;i++){
                if(flag[i]==0 && weight[i]<min){
                    k=i;//K为U集合到V集合中找到的顶点
                    min=weight[i];//min找到了最小值的位置
                }
            }
            //从这个最短的路径对应的顶点开始找下一轮
            flag[k]=1;
            //修正当前最短路径
            for(int i=0;i<9;i++){
                //如果经过V顶点的路径比现在的路径短,新更新
                if(flag[i]==0 && (min+array[k][i])<weight[i]){
                    weight[i]=min+array[k][i];//修改路径长度
                    path[i]=k;//保存前驱
                }
            }
        }
        for(int i=0;i<path.length;i++){
            System.out.print(path[i]+" ");
        }
        System.out.println();
        for(int i=0;i<weight.length;i++){
            System.out.print(weight[i]+" ");
        }
        //打印结果
        int v=8;
        while(v!=0){
            System.out.print(path[v]);
            v=path[v];
        }
    }