Dijkstra最短路径算法

操作步骤

(1) 初始时,S只包含起点vs;U包含除vs外的其他顶点,且U中顶点的距离为"起点vs到该顶点的距离"[例如,U中顶点v的距离为(vs,v)的长度,然后vs和v不相邻,则v的距离为∞]。
(2) 从U中选出"距离最短的顶点k",并将顶点k加入到S中;同时,从U中移除顶点k。
(3) 更新U中各个顶点到起点vs的距离。之所以更新U中顶点的距离,是由于上一步中确定了k是求出最短路径的顶点,从而可以利用k来更新其它顶点的距离;例如,(vs,v)的距离可能大于(vs,k)+(k,v)的距离。
(4) 重复步骤(2)和(3),直到遍历完所有顶点。


image.png

image.png

image.png

image.png

image.png

image.png

image.png

image.png

代码实现

package dataStructure.graph;

import java.util.ArrayList;
import java.util.List;

/**
 * Dijkstra最短路径
 */
public class ShortestPathDijkstra {
    private int[][] matrix;//邻接矩阵
    private int N = Integer.MAX_VALUE;//表示正无穷
    private String[] vertexes;//表示顶点集合

    private void createGraph(int index) {
        matrix = new int[index][index];
        vertexes = new String[index];

        int[] v0 = {0, 1, 5, N, N, N, N, N, N};
        int[] v1 = {1, 0, 3, 7, 5, N, N, N, N};
        int[] v2 = {5, 3, 0, N, 1, 7, N, N, N};
        int[] v3 = {N, 7, N, 0, 2, N, 3, N, N};
        int[] v4 = {N, 5, 1, 2, 0, 3, 6, 9, N};
        int[] v5 = {N, N, 7, N, 3, 0, N, 5, N};
        int[] v6 = {N, N, N, 3, 6, N, 0, 2, 7};
        int[] v7 = {N, N, N, N, 9, 5, 2, 0, 4};
        int[] v8 = {N, N, N, N, N, N, 7, 4, 0};

        matrix[0] = v0;
        matrix[1] = v1;
        matrix[2] = v2;
        matrix[3] = v3;
        matrix[4] = v4;
        matrix[5] = v5;
        matrix[6] = v6;
        matrix[7] = v7;
        matrix[8] = v8;

        vertexes[0] = "v0";
        vertexes[1] = "v1";
        vertexes[2] = "v2";
        vertexes[3] = "v3";
        vertexes[4] = "v4";
        vertexes[5] = "v5";
        vertexes[6] = "v6";
        vertexes[7] = "v7";
        vertexes[8] = "v8";
    }

    /**
     * Dijkstra最短路径
     */
    public void dijkstra(int vs){
        //表示最短路径是否获取成功
        boolean[] flag = new boolean[vertexes.length];
        //还未求出的最短路径
        int[] U = new int[vertexes.length];
        //前驱顶点数组:用于打印
        int[] pre = new int[vertexes.length];
        //已求出的最短路径的节点
        String[] S = new String[vertexes.length];

        //初始化
        for (int i = 0; i < vertexes.length; i ++) {
            flag[i] = false;
            U[i] = matrix[vs][i];
            pre[i] = 0;
        }

        //将vs移除
        S[0] = vertexes[vs];
        flag[vs] = true;
        U[vs] = 0;

        int k = 0;
        for(int i = 1; i < vertexes.length; i++){
            //获取最短路径的节点:该点到vs的值最小
            int min = N;
            for(int j = 0; j < vertexes.length; j ++){
                if(flag[j] == false && U[j] < min){
                    min = U[j];
                    k = j;
                }
            }

            //将k放在s中
            S[i] = vertexes[k];
            flag[k] = true;

            //更新未访问的节点:v[1]的集体加个最短路径
            for (int j = 0; j < vertexes.length; j++) {
                int tmp = (matrix[k][j] == N) ? N : (min + matrix[k][j]);
                //未访问过且值不为0的更新
                if(flag[j] == false && (tmp < U[j])){//若tmp小于U[j],只用一种可能是U[j]=0
                    U[j] = tmp;
                    pre[j] = k;//下标节点
                }
            }
        }

        //打印最短路径
        System.out.println("起始顶点: " + vertexes[vs]);
        for(int i = 0; i < vertexes.length; i++){
            System.out.println("最短路径(" + vertexes[vs] + "," + vertexes[i] +"):" + U[i] + "   ");

            //输出v0->v1->v2->v4
            List<String> path = new ArrayList<>();
            int j = i;
            while(true){
                path.add(vertexes[j]);

                if(j == 0){
                    break;
                }

                j = pre[j];
            }
            for(int x = path.size() -1; x >= 0; x--){
                if(x == 0){
                    System.out.println(path.get(x));
                }else{
                    System.out.print(path.get(x) + "->");
                }
            }
        }

        System.out.println("顶点放入s的顺序:");
        //v0-->v1-->v2-->v4-->v3-->v5-->v6-->v7-->v8
        for(int i = 0; i < vertexes.length; i++){
            System.out.print(S[i]);

            if(i != vertexes.length - 1){
                System.out.print("-->");
            }
        }

    }

    public static void main(String[] args) {
        ShortestPathDijkstra shortestPathDijkstra = new ShortestPathDijkstra();
        shortestPathDijkstra.createGraph(9);
        shortestPathDijkstra.dijkstra(0);
        /**
         起始顶点: v0
         最短路径(v0,v0):0   
         v0
         最短路径(v0,v1):1   
         v0->v1
         最短路径(v0,v2):4   
         v0->v1->v2
         最短路径(v0,v3):7   
         v0->v1->v2->v4->v3
         最短路径(v0,v4):5   
         v0->v1->v2->v4
         最短路径(v0,v5):8   
         v0->v1->v2->v4->v5
         最短路径(v0,v6):10   
         v0->v1->v2->v4->v3->v6
         最短路径(v0,v7):12   
         v0->v1->v2->v4->v3->v6->v7
         最短路径(v0,v8):16   
         v0->v1->v2->v4->v3->v6->v7->v8
         顶点放入s的顺序:
         v0-->v1-->v2-->v4-->v3-->v5-->v6-->v7-->v8
         */
    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容