Dijkstra算法

参考博客

算法理解

首先Dijkstra算法是一个贪心算法,时间复杂度是O(n^2).它求得的是从一个源点到达其他任何节点的最短路径。既能得到最短的代价也能通过prev数组找到这条路径。但是当需要知道图中非常多次的两点间最短路径时,可以考录弗洛伊德算法,弗洛伊德是得到的是任意两点之间的最短路径和代价但是时间复杂度是O(n^3)


public class Dijkstra {
    static int maxMapPoints = 600;
    static int maxSetPoints = 50;
    static int mapPoints=6;//图中节点的个数
    static int setPoints;//集合众节点的个数
    static int[][] map = new int[maxMapPoints][maxMapPoints];
    static int[] dist  = new int[maxMapPoints];
    static int[] prev = new int[maxMapPoints];
    public static void main(String[] args){
        buildMap();
        DijkstraMethod(0);
        for(int i=0;i<mapPoints;i++){
            System.out.print(dist[i]+" ");
        }
        System.out.println();
        for(int i=0;i<mapPoints;i++){
            System.out.print(prev[i]+" ");
        }
        System.out.println();
        printRoute(5);
    }
    public static void buildMap(){
        for(int i=0;i<mapPoints;i++){
            for(int j=0;j<mapPoints;j++){
                map[i][j] = Integer.MAX_VALUE;
            }
        }
        map[0][1] = 6;
        map[0][2] = 3;
        map[1][0] = 6;
        map[1][2] = 2;
        map[1][3] = 5;
        map[2][0] = 3;
        map[2][1] = 2;
        map[2][3] = 3;
        map[2][4] = 4;
        map[3][1] =5;
        map[3][2] = 3;
        map[3][4]  = 2;
        map[3][5] = 3;
        map[4][2] = 4;
        map[4][3] = 2;
        map[4][5] = 5;
        map[5][3] = 3;
        map[5][4] = 5;
    }
    //打印v0到vj的路径 此方法依赖DijkstraMethod和buildMap方法
    //还有输出的路径是倒序的
    public static void printRoute(int vj){
        if(vj<0 || vj>mapPoints || prev[vj]==-1){
            System.out.println("没有路径");
        }
        int index = vj;
        while(index!=-1){
            System.out.print(index+" ");
            index = prev[index];
        }
    }
    //集合S代表已经确定好最短路径的集合 集合U表示未找到最短路径的集合
    public static void DijkstraMethod(int v0){
        int n = mapPoints;
        boolean[] S = new boolean[mapPoints];//判断是否在S集合当中
        //初始化
        for(int i =0;i<n;i++){
            dist[i] = map[v0][i];
            S[i] = false;
            if(dist[i]==Integer.MAX_VALUE){
                prev[i]= -1;
            }else{
                prev[i] = v0;
            }
        }
        dist[v0] = 0;
        S[v0] = true;

        //选出n-1个点到S中
        for(int i=0;i<n-1;i++){
            int mindist = Integer.MAX_VALUE;
            int u = v0;
            //从集合U当中找出一个最小距离的点j 下标存在u中 既dist[j]最小
            for(int j=0;j<n;j++){
                if(!S[j] && dist[j]<mindist){
                    u = j;
                    mindist = dist[j];
                }
            }
            S[u] = true;
            //更新所有U中的集合,如果v0经过u到U集合中点的距离小于直接到U的距离则更新
            for(int j=0;j<n;++j){
                if(!S[j] && map[u][j]<Integer.MAX_VALUE){
                    if(dist[u]+map[u][j]<dist[j]){
                        dist[j] = dist[u] +map[u][j];
                        prev[j] = u;
                    }
                }
            }
        }
    }
}

你可能感兴趣的:(dijkstra)