【图论】【最短路径】Floyed算法和Dijkstra算法

最短路径在数据结构的教材上有两种生成算法:Floyed算法和Dijkstra算法

Floyed算法

算法思想:

  通过三个for循环,求出各个点距离其他各个点的最短距离。其中,最外层for循环遍历中间节点k,第二第三层循环起点i,终点j;算法思想:如果i节点到k节点的距离 加上 k节点到j节点的距离,那么i节点到j节点的距离就更新为dis[i][k] + dis[k][j],等遍历完所有中间节点,就得到了全局的最短路径。

public void floyed() {
        for (int k = 1; k <= n; k++) {
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    if (data[i][j] > data[i][k] + data[k][j]) {
                        data[i][j] = data[i][k] + data[k][j];
                    }
                }
            }
        }

        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= n; j++) {
                System.out.println(String.format("%d->%d:%d", i, j, data[i][j]));
            }
        }
    }
Floyed算法

 

Dijkstra算法

算法思想:

  找到指定节点距离其他节点的最短距离,也就是说该算法找的只是1个节点的最短距离。先指定一个初始节点x,并标记为已访问,然后初始化改节点距离其他节点的距离,接着找到距离最近的一个节点m,标记为已访问,然后计算经过m做中介,是否缩短了节点x到其他未访问节点的距离,有缩短则更性。即:dis[i] > dis[m]+edge[m][i] 那么dis[i] = dis[m]+edge[m][i] 。

  Dijkstra算法的过程和Kruskal算法(最小生成树)有些类似,都在寻找最小的问题,然后更新全局的距离。不过Dijkstra每次找到的是距离最近的点,而Kruskal找到的是最短的边。

public void dijkstra(int x) {
        int pos = x;
        int join[] = new int[n + 1];
        int pre[] = new int[n + 1];
        pre[x] = 0;
        join[x] = 1;

        for (int i = 1; i <= n; i++) { // 初始化dis
            if (join[i] == 0) {
                dis[i] = data[pos][i];
            }
        }

        for (int i = 0; i < n - 1; i++) { //除开起始点,需要查找n-1次
            int min = max;
            for (int j = 1; j <= n; j++) {
                if (join[j] == 0 && dis[j] != 0 && min > dis[j]) {
                    min = dis[j];
                    pos = j;
                }
            }
            join[pos] = 1;
            for (int j = 1; j <= n; j++) {
                if (join[j] == 0 && dis[j] > dis[pos] + data[pos][j]) {
                    dis[j] = dis[pos] + data[pos][j];
                    pre[j] = pos; // 记录下前置节点,用于输出路径
                }
            }
        }

        for (int i = 1; i <= n; i++) {
            if (i == x) {
                continue;
            }
            System.out.println(String.format("%s -> %s: %s", x, i, dis[i]));
        }
        for (int i = 1; i <= n; i++) {
            int preN = pre[i];
            if (preN > 0) {
                System.out.println(String.format("%d pre node is %d", i, preN));
            } else {
                System.out.println(String.format("%d has no pre node", i));
            }
        }
    }
Dijkstra

 

posted @ 2018-06-23 16:59  buliang  阅读(546)  评论(0编辑  收藏  举报