图-最短路径-迪杰斯特拉算法

2020-08-13  本文已影响0人  如春天

最短路径

在网图和非网图中,最短路径的含义是不同的。对于非网图,由于其边上没有权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径。而对于网图,最短路径,是指两顶点之间经过的边上权值之和最少的路径。


和最小生成树的区别:

最小生成树能够保证整个拓扑图的所有路径之和最小,但不能保证任意两点之间是最短路径。
最短路径是从一点出发,到达目的地的路径最小。
Prim 和 Dijkstra 代码非常相似,都是这样一个大体步骤:初始化,找最小值,更新权值数组。注意对比他们的代码。

迪杰斯特拉算法(Dijkstra)

按路径长度递增的次序产生最短路径。

一步一步求出他们之间顶点的最短路径,过程中都是基于已经求出的最短路径的基础上,求得更远顶点的最短路径,最终得到你要的结果。

#include "邻接矩阵.h"
#define MAXVEX 9
#define INF 65535
typedef int Patharc[MAXVEX];
typedef int ShortPathTable[MAXVEX];
void
Dijkstra(MGraph G, int begin, Patharc *P, ShortPathTable *D)
{
    /*
    ShortPathTable数组 表示 begin 到 某顶点的"最短路径和"
    Patharc数组 比如P[v] = w,表示 v的前驱为w
    */
    int v, w, k, min;/*k用来存放最小值min对应的顶点下标*/
    int final[MAXVEX]; /*存放begin 到 某顶点 是否已经求得最短路径,如果begin到v2已经求得,final[2] = 1*/
    for(v = 0; v < G.numVertexes; v++)
    {
        final[v] = 0; /*所有顶点都未求得最短路径*/
        (*D)[v] = G.arc[begin][v];
        (*P)[v] = -1;/*这里书上是0,是错误的,更正为-1后,每当一个结点的前驱为-1,即等同于它的前驱为begin
        如初始化第一次还是计算从begin到各顶点的权值。如果D[v] = 3;P[v] = -1; 就表示从begin到v的最短路径和为3; 
        */
    }
    (*D)[begin] = 0; /*起始点到起始点的路径为0,如果对角线用INF表示这行代码是必须的,如果用0表示对角线,这行代码多余*/
    final[begin] = 1;/*起始点到起始点不需要求路径*/

    /*初始化结束 开始循环生成最短路径*/
    for(v = 1; v < G.numVertexes; v++)
    {
        /*这里为什么循环是从1开始的,因为顶点begin已经再=在最短路径中,不需要再求*/
        /*寻找D数组中没有被纳入Final数组的部分的最小值*/
        min = INF;
        for(w = 0; w < G.numVertexes; w++)
        {
            if(!final[w] && (*D)[w] < min)
            {
                k = w;
                min = (*D)[w];
            }
        }
        final[k] = 1;
        /*找到最小值,相应下标顶点纳入final数组,=1表面该顶点已经在最小路径中。*/
        /*更新从begin到各未被纳入顶点的值,如果小于先前的最小路径和,就更新,并把顶点的前驱在P数组中置为之前求得的k,这里有这样一个对应关系*/
        for(w = 0; w < G.numVertexes; w++)
        {
            if(!final[w] && (min+G.arc[k][w] < (*D)[w]))
            {
                (*D)[w] = min + G.arc[k][w];
                (*P)[w] = k;
            }
        }
    }
}

上一篇下一篇

猜你喜欢

热点阅读