简洁明了的迪杰斯特拉算法

作用,求图中某一顶点到其余各顶点的最短路径

思想:过程类似于普利姆算法,但不同的是一直更新这个固定结点与新结点的总路径距离,而普利姆算法是新的结点与剩余的结点间的两点距离,下面我结合算法实例进行解释

如下图所示:

这里写图片描述

解释:以端点1作为一个基本点(以其他的作为基本点都可以),接下来用一个数组存储各个端点到端点1的距离,(注意,只有这一个距离,也可以叫存储的距离为最短距离),把端点0到端点1的距离存入save[]数组(比对各条最短距离,发现端点0,2到端点1的距离最短,两者随便取一个,这里我选择取0这个端点),同时将端点0做好相应标志(表示该端点已经被访问过)第二步,比对剩余端点到端点1的最短距离,端点0到端点1有两条路径长度save[0]与save[2]+a.g[2][0]比对,save[0]=5<7,save[0]不变化(旧的长度比新出来的路径长度,如果旧的长度比较长,则save[i]不变,反之,save[i]变成新的路径长度),相应的save[3]=7,save[4]=8;在这些未做标志的数组里面查找最短边,即为端点0,所以将端点0做好标志(表示已经确认了端点1到端点0的最短距离),按照该种规则,直到所有点都已经做完相应标志即可(笔者在这里没有做path数组来存储路径的说明,同学们可通过我下面的代码来理解它组)

//v0为初使结点,save数组存储v0与剩下所有结点的最短路径,挑选出各结点
//路径中最短的一条,录入s数组中,同时对该结点做好标志,以及path数组
//存入该结点前一个端点。按照这个规则,直到所有结点遍历完全
int visit[max];
int path[max];
int save[max];
void djstl(ag a,int v)
{
    visit[v]=1;
    int l,term=N;
    for(i=0;i<a.n;i++) //先将第一个结点以及对应的连接结点的行为搞好
    {
        if(visit[i]==0)
        save[i]=a.g[v][i];
        if(term>a.g[v][i])
        {
            term=a.g[v][i];
            j=i;
        }
    }
    path[j]=v;
    visit[j]=1;
    k=2;
    //接下来让剩下的结点按照此规则进行遍历
    while(k<a.n)
    {
        for(i=0;i<a.n;i++)
        {
            if(visit[i]==0)
            {
                if(save[i]>save[j]+a.g[j][i])
                {
                    save[i]=save[j]+a.g[j][i];
                    path[i]=j;//放在这里巧妙地解决了新旧路径存放结点问题
                }
                if(term>save[j]+a.g[j][i])
                {
                    term=save[j]+a.g[j][i];
                    j=i;
                }
            }
        }
         visit[j]=1;
         k++;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42373888/article/details/81534882