迪杰斯特拉算法(C语言实现)

有向图

如上图,求以a为源点到个顶点的最短路劲。

#include "stdio.h"
#include "stdlib.h"
//用一个最大数表示顶点之间不相关
#define MAX 999
//设置顶点个数
#define MAX_VERTEX_NUM 7
//表示顶点之间不关联的常量
int INFINITY = MAX;
//记录顶点是否被访问过,已访问值为1,未访问值为0
int final[MAX_VERTEX_NUM];
//从指定顶点到其他各个节点的最短路径
int dist[MAX_VERTEX_NUM];
//记录路径
char path[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
//实现构造图的矩阵关系,在图初始化的时候赋值到G.arcs[][]中
int temp[MAX_VERTEX_NUM][MAX_VERTEX_NUM]={
                                            { 0, 24, 8, 15,MAX,MAX,MAX},
                                            {MAX, 0,MAX,MAX, 6,MAX,MAX},
                                            {MAX,MAX, 0,MAX, 7, 3,MAX},
                                            {MAX,MAX,MAX, 0,MAX,MAX, 4},
                                            {MAX,MAX,MAX,MAX, 0,MAX, 9},
                                            {MAX,MAX,MAX, 5, 2, 0, 10},
                                            {MAX, 3,MAX,MAX,MAX,MAX, 0}
                                            };
//图中顶点关系的二维数组表示
typedef struct ArcCell{
    int adj;
    char *info;
}AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
//图的结构体,vexs顶点的一维数组
//AdjMatrix类型的关系矩阵,vexnum为顶点个数,arcnum为关系个数。
typedef struct{
    char vexs[MAX_VERTEX_NUM];
    AdjMatrix arcs;
    int vexnum;
    int arcnum;
}MGraph;
//初始化图,依次初始化顶点为abc...
//然后把实现已构造temp[][]矩阵赋值到图的G.arcs[][]矩阵关系中
MGraph initMGraph(MGraph G)
{
    int i,j;
    char char_a='a';
    //依次构建顶点为a,b,c...
    for(i=0;i<MAX_VERTEX_NUM;i++)
    {
        G.vexs[i]=(char)((int)char_a+i);
        printf("%c ",G.vexs[i]);
    }
    printf("\n");
    //G.arcs[][]=temp[][]
    for(i=0;i<MAX_VERTEX_NUM;i++)
    {
        for(j=0;j<MAX_VERTEX_NUM;j++)
        {
            G.arcs[i][j].adj=temp[i][j];
            printf("%3d ",G.arcs[i][j].adj);
        }
        printf("\n");
    }
    G.vexnum=7;
    G.arcnum=12;
    return G;
}
//判定指定顶点到各顶点中路径最小的
//需要去除已经访问的顶点final[i]!=1再做最小路径比较
//返回下标
int mininum(int* dist)
{
    int i,min=MAX,min_i;
    for(i=0;i<MAX_VERTEX_NUM;i++)
    {
        if(dist[i]!=0&&dist[i]<min&&final[i]!=1)
        {
            min=dist[i];
            min_i=i;
        }
    }
    if(min==MAX)
       return -1;
    return min_i;
}
//顶点是否在图中
int exist_v(MGraph G,char u)
{
    int i,s=-1;
    for(i=0;i<G.vexnum;i++)
       if(G.vexs[i]==u)
          s=i;
    if(s==-1)
       return 0;
    return 1; 
}
//图最小路径算法
void ShortestPath_DIJ(MGraph G,char u)
{
    int s=-1,i,j,k,min_i,path_p,count,c;
    char v;
    //查找源点的下标,用s记录
    for(i=0;i<G.vexnum;i++)
       if(G.vexs[i]==u)
          s=i;
    for(i=0;i<G.vexnum;i++)
    {
        final[i]=0;
        dist[i]=G.arcs[s][i].adj;
        v=G.vexs[i];
        if(dist[i]<INFINITY&&dist[i]!=0)
        {
           path[i][0]=u;
           path[i][1]=v;
           printf("init path%d=%c-%c-\n",i,path[i][0],path[i][1]);
        }
    }
    //初始化从源点到源点的路径为0,把源点设置为已访问(也就是把源点加入到S中)
    dist[s]=0;
    final[s]=1;
    for(i=1;i<G.vexnum;i++)
    {
        min_i=mininum(dist);
        printf("\nmin_i=%d ",min_i);
        printf("\tvisited index---");
        for(c=0;c<G.vexnum;c++)
            if(final[c]==1)
               printf("%d ",c);                      
        //当前中间点与图中任何顶点都不关联
        if(min_i==-1)
            break;
        final[min_i]=1;
        //更新其他顶点最短路径
        for(k=0;k<G.vexnum;k++)
        {
            if(G.arcs[min_i][k].adj!=0)
            {
                //更新路劲值,路径表示(如a-b-c)
                if((dist[min_i]+G.arcs[min_i][k].adj)<dist[k])
                {  
                  dist[k]=dist[min_i]+G.arcs[min_i][k].adj;
                  for(path_p=0;path[min_i][path_p]!=0;path_p++)
                       path[k][path_p]=path[min_i][path_p];
                  path[k][path_p]=G.vexs[k];
                }
            }
        }
        //输出执行一次后的dist[]最短路径情况
        printf("\n----------------------------------------------------\n");
        for(count=0;count<G.vexnum;count++)
        {
          if(dist[count]==MAX)
            printf("\tMAX");
          else
            printf("\t%3d ",dist[count]);
        } 
    }
    //输出路径表示
    printf("\n---------the--------------path----------------------");
    for(count=0;count<G.vexnum;count++)
    {
        printf("\npath%d=",count);
        for(j=0;j<G.vexnum;j++)
              if(path[count][j]&&path[count][j]!=path[count][j-1])
                 printf("%c-",path[count][j]);
    }
}
int main(void)
{
    int i,j;
    char v;
    MGraph G;
    //初始化图
    G=initMGraph(G);
    //计算最短路径
    v='a';
    if(exist_v(G,v))
        ShortestPath_DIJ(G,v);
    else
        printf("the vertex %c has no path",v);
    system("pause");
    return 0;
}