常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法

Dijkstra算法(迪杰斯特拉算法)

 通过普里姆算法与克鲁斯卡尔算法,我们可以运算出最优全连通结果。但若要计算某个顶点与其他顶点连接的最短距离时,则需要了解地杰斯特拉算法(D算法)与弗洛伊德算法(F算法)

【例子】如下图,有一个7村庄(A~G),需要求得G村庄到其他村庄的最短距离

常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法_第1张图片

D算法流程: 

visited_vertex数组:存储顶点是否被访问的信息(1为被访问)

pre_visited数组:存储对应结点的父节点

distance数组:存储对应结点距起始结点的距离

常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法_第2张图片

常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法_第3张图片

常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法_第4张图片

常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法_第5张图片

常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法_第6张图片 迪杰斯特拉算法是典型最短路径算法,用于计算一个结点到其他结点的最短路径。它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。了解算法本质,就要读懂上面的流程图。

代码实现:

下面的代码实现有点复杂,需要借助两个类完成,一个是图结构的类,负责图的绘制与地杰斯特拉算法主体操作。一个是visitedVertex类,负责存储地杰斯特拉算法需要使用的数据与方法

其中 更新顶点数组数据的方法(update),找到最短距离顶点并更新数据的方法(updateVertex),地杰斯特拉算法主体(djs)三个方法是整个代码的灵魂,三者具有一定的依赖关系

package cn.dataStructureAndAlgorithm.demo.tenAlgorithm.Dijkstra;

import java.util.Arrays;
interface IConstant{//常量类
    public static final int INF = 99999;//定义INF为全局常量,INF为填充数据
}
public class 地杰斯特拉算法_Dijkstra_最短路径问题 implements IConstant {
    public static void main(String[] args) {
        //准备图
        char[] vertex={'A','B','C','D','E','F','G'};
        int[][] matrix={
                {INF,5,7,INF,INF,INF,2},
                {5,INF,INF,9,INF,INF,3},
                {7,INF,INF,INF,8,INF,INF},
                {INF,9,INF,INF,INF,4,INF},
                {INF,INF,8,INF,INF,5,4},
                {INF,INF,INF,4,5,INF,6},
                {2,3,INF,INF,4,6,INF},
        };
        Graph graph=new Graph(vertex,matrix);
        //调用地杰斯特拉算法
        graph.djs(6);
    }
}
class Graph{
    private char[] vertex;//顶点数组
    private int[][] matrix;//邻接矩阵
    private VisitedVertex visitedVertex;//对已运算的顶点进行操作的类

    public Graph(char[] vertex, int[][] matrix) {
        this.vertex = vertex;
        this.matrix = matrix;
    }

    /**
     * 地杰斯特拉算法主体
     * @param index 起始顶点
     */
    public void djs(int index){
        //进行对于起始顶点的初始化操作
        visitedVertex=new VisitedVertex(vertex.length,index);
        update(index);
        //循环顶点个数-1次,来找到从起始顶点到每个顶点的最短距离
        for (int i=1;i
==========(visited_vertex)=========
1 1 1 1 1 1 1 
==========(pre_visited)=========
6 6 0 5 6 6 0 
==========(distance)=========
2 3 9 10 4 6 0 

G到A~G的最短路径分别为:2,3,9,10,4,6,0

 

 

Floyd算法(弗洛伊德算法)

 相较于地杰斯特拉算法,弗洛伊德算法十分简单易懂。但简单易懂的代价就是时间复杂度很高(O(n^3))

【例子】如下图,有一个7村庄(A~G),需要求得某一村庄到其他村庄的最短距离

常用十大算法_迪杰斯特拉(Dijkstra)算法,弗洛伊德(Floyd)算法_第7张图片

 F算法分析:

弗洛伊德算法的核心是建立了三个顶点的关系,算法从A~G中遍历选取一个顶点 k 作为中间顶点,再从A~G中选取一个顶点 i 作为起始顶点,再A~G从中选取一个顶点 j 作为终止顶点。将 i 到 k,k 到 j 这两段距离求和,求和结果与原先的 i 到 j 的距离比较,若更小就采用这段距离,反之仍用原有距离。

比如说:以A为中间顶点,选取C为起始顶点,G为终止顶点,所得到的的C到G的距离为7+2=10,再与原有距离进行比较,小时采用10

这样的算法十分暴力,需要三层循环。

代码实现:

package cn.dataStructureAndAlgorithm.demo.tenAlgorithm.Floyd;

import java.util.Arrays;
interface IConstant{//常量类
    public static final int INF = 99999;//定义INF为全局常量,INF为填充数据
}
public class 弗洛伊德算法_Floyd_最短路径问题 implements IConstant{
    public static void main(String[] args) {
        //准备图
        char[] vertex={'A','B','C','D','E','F','G'};
        int[][] matrix={
                {0,5,7,INF,INF,INF,2},
                {5,0,INF,9,INF,INF,3},
                {7,INF,0,INF,8,INF,INF},
                {INF,9,INF,0,INF,4,INF},
                {INF,INF,8,INF,0,5,4},
                {INF,INF,INF,4,5,0,6},
                {2,3,INF,INF,4,6,0},
        };
        Graph graph=new Graph(vertex,matrix);
        graph.floyd();
    }
}
class Graph{
    private char[] vertex;
    private int[][] dis;
    private int[][] pre;

    public Graph(char[] vertex, int[][] matrix) {
        this.vertex = vertex;
        this.dis = matrix;
        pre = new int[vertex.length][vertex.length];
        for (int i=0;i
由A到A~G的最短距离分别为:[0] [5] [7] [12] [6] [8] [2] 
由B到A~G的最短距离分别为:[5] [0] [12] [9] [7] [9] [3] 
由C到A~G的最短距离分别为:[7] [12] [0] [17] [8] [13] [9] 
由D到A~G的最短距离分别为:[12] [9] [17] [0] [9] [4] [10] 
由E到A~G的最短距离分别为:[6] [7] [8] [9] [0] [5] [4] 
由F到A~G的最短距离分别为:[8] [9] [13] [4] [5] [0] [6] 
由G到A~G的最短距离分别为:[2] [3] [9] [10] [4] [6] [0] 

 


其他常用算法,见下各链接

【常用十大算法_二分查找算法】

【常用十大算法_分治算法】

【常用十大算法_贪心算法】

【常用十大算法_动态规划算法(DP)】

【常用十大算法_KMP算法】

【常用十大算法_普里姆(prim)算法,克鲁斯卡尔(Kruskal)算法】

【常用十大算法_回溯算法】

 

【数据结构与算法整理总结目录 :>】<-- 宝藏在此(doge)  

 

你可能感兴趣的:(数据结构与算法)