图之Dijkstra算法(邻接表)---最短路径

算法描述:

Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径,主要特点是以起点为中心向外层扩展,直到扩展到终点为止.该算法要求图中不存在负权边.

算法思想:

设G=(V,E)是一个带权的有向图, 把图中顶点集合分为两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径,就将加入到集合S中,直到全部顶点都加到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按照最短路径长度的递增次序依次把第二组的顶点加入到S中,在加入过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度, 此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包含S中的顶点为中间顶点的当前最短路径长度.

代码如下:

void Dijkstra(AdjList *G,int start,int disk[],int path[][MAXVEX])
{
    int i,j,mindist,k,t;
    ArcNode *p;
    for(i=1;i<=G->vexnum;i++){    //初始化最短路径数组disk,和标记此顶点是否已经找到最短路径的path[i][0],等于0表示没有找到,等于1表示找到.
        disk[i]=INFINE;
        path[i][0]=0;
    }
    p=G->vertex[start].head->next;
    while(p){                                  //保存源点到和此源点相关的顶点的路径.
        disk[p->adjvex]=p->weight;
        path[p->adjvex][1]=start;
        path[p->adjvex][2]=p->adjvex;
        path[p->adjvex][3]=0;
         p=p->next;
    }
    path[start][0]=1;               //源点标记为为1,其最短路径为0.此顶点以后不会再用到
    for(i=2;i<=G->vexnum;i++){                //选择最最短的路径
         mindist=INFINE;
        for(j=1;j<=G->vexnum;j++){
            if(!path[j][0] && disk[j] < mindist){
                k=j;                                         
                mindist=disk[j];
            }
        }
        if(mindist == INFINE){         //如果没有找到最短的路径,则说明从此源点不能到任何其他顶点,直接返回.
            return;
        }
        path[k][0]=1;                  //标记找到最小路径的顶点,此顶点以后不会再用到.
        p=G->vertex[k].head->next;
        while(p){
            if(!path[p->adjvex][0]&& disk[p->adjvex] > disk[k]+ p->weight){     //更新disk,使其从保持从源点到和此顶点相关的顶点的路径最短.           
                //printf("p->ad:%d ",p->adjvex);
                disk[p->adjvex]=disk[k]+p->weight;
                t=1;
                while(path[k][t]!=0)      //记录最新的路径
                {
                    path[p->adjvex][t]=path[k][t];
                    t++;
                }
                path[p->adjvex][t]=p->adjvex;
                path[p->adjvex][t+1]=0;                       //path[i][t+1]之前的都是最短路径所要经过的顶点,从t+1这里停止,作为最后输出路径的判断条件
            }
            p=p->next;
        }
    }
}

完整代码详见:https://github.com/liuhangyang/Data_Structure_and_Algorithm/blob/master/%E7%AC%AC%E4%B8%83%E7%AB%A0/linjiebiao.c


你可能感兴趣的:(图之Dijkstra算法(邻接表)---最短路径)