图的最短路径(Dijkstra算法和Floyd算法)

601 阅读3分钟
  • Dijkstra算法

    • 算法思路

      思路:一步一步计算出起始点到所有顶点的额最短路径(要全部循环得到最短路径,而不是仅仅遍历起始点到终点) 假设冲0开始找最短路径, 第一步创建三个数组 final 数组 用于记录是否找到了0到该顶点的最短路径 如果找到标记为1, 然后是weight数组用于记录 到该顶点所需要的权值,最后一个数组是parent数组,用于记录当前顶点的前驱顶点的索引,循环多有顶点 如果出现到达 当前顶点的前置要小于final数组中记录的权值那么就更新三个数组

      循环解析: 第一次 现将起始点标记为已经找到, 然后对应的到所有顶点的权值全部都赋值 第一次循环先遍历weight数组 然后找出最短的那个距离k 然后在记录最短的权值w,然后final[k] = 1 然后再遍历weight数组,找到所有k到个顶点的权值,然后计算冲0-k的然后冲k-各个顶点的权值作对比, 更小的话 留更小的值 然后记录当前q结点的前驱结点,其余循环也如此 找到更小的权值之后就替换,最终就可以得到0到 所有顶点的最短路径

    • 实现代码

    void dijkstra(Graph G){
        
        int final[9];
        int parent[9];
        int weight[9];
        
        //第一步初始化数组
        for(int i = 0; i < G.numVertexes; i ++){
            if(i == 0){
                final[i] = 1;
                parent[i] = -1;
            }else{
                final[i] = 0;
                parent[i] = 0;
            }
            
            
            weight[i] = G.arc[0][i];
        }
        
        int min = INFINITYC;
        int k = 0;
        for(int i = 1; i < G.numVertexes; i ++){
            
            min = INFINITYC;
            for(int j = 0; j < G.numVertexes; j ++){
                if(final[j] != 1 && min > weight[j]){
                    min = weight[j];
                    k = j;
                }
            }
            final[k] = 1;
            
            
            for(int j = 0; j < G.numVertexes; j ++){
                if(final[j] != 1 && G.arc[k][j] + min < weight[j]){
                    weight[j] = G.arc[k][j] + min;
                    parent[j] = k;
                }
            }
        }
        
    }
    
  • Floyd算法

    • 算法思路

      和Dijkstra算法区别在于,Dijkstrazz只计算出了冲起始点到所有顶点的最短路径 而Floyd算法是计算出了 所有顶点到所有顶点的最短路径,大概的思路就是,先 创建i两个二维数组分别用于存储最小权值和,顶点的前驱顶点的索引, 步骤就是: 首先要初始化weight数组和parent数组默认最短路径就是按照顺序的最短路径 第一层循环,是顶点中间的中间值,在复制最短路径的时候需要根据中间值来判断 (其实意思就是,比较从起始顶点到目的顶点的距离更近还是,冲其实顶点打牌中间顶点 再到目的顶点的距离更近,weight[i][k] + weight[k][j] < weight[i][j]) 第二三层循环就是开始比较所有点顶点到目的顶点的权值了,就是比较上一次结果和 以k为中间跳板更近,更近的话则更新数组就好(看思路建议先看一下代码的变量声明)

    • 实现代码

    void floyd(Graph G){
        int weight[MAXVEX][MAXVEX];
        int parent[MAXVEX][MAXVEX];
        
        //初始化数组
        for(int i = 0; i < G.numVertexes; i ++){
            for(int j = 0; j < G.numVertexes; j ++){
                weight[i][j] = G.arc[i][j];
                parent[i][j] = j;
            }
        }
        
        //开始循环找最短路径
        for(int k = 0; k < G.numVertexes; k ++){
            
            for(int i = 0; i < G.numVertexes; i ++){
                for(int j = 0; j < G.numVertexes; j ++){
                    if(weight[i][k] + weight[k][j] < weight[i][j]){
                        weight[i][j] = weight[k][i] + weight[k][j];
                        parent[i][j] = parent[i][k];
                    }
                }
            }
        }
    }