算法基本思想:
1、取开始顶点,得到所有邻顶点权,记入最短路径表;
2、找出具有最小权的邻顶点,记录下到该点的权值并标记为已遍历;
3、从上述最小权相邻顶点出发,把到未遍历顶点的权值加上之前得到的最小权值与最短路径表中到各点的权值进行比较,如果前者较小的话则更新最短路径表数据,并记录前驱顶点;
4、在最短路径表中寻找最小的权值,得到的顶点重复步骤2,直到遍历完成。
#include <stdio.h>
#define MAXVEX 9
#define INFINITY 65535
typedef int Pathmatirx[MAXVEX]; //用于存储最短路径下标的数组
typedef int ShortPathTable[MAXVEX]; //用于存储到各点最短路径的权值和
typedef struct MGraph
{
int numVertexes;
int arc[9][9];
}MGraph;
void dijkstra(MGraph G,int v0,Pathmatirx *P,ShortPathTable *D)
{
int v,w,k,min;
int final[MAXVEX]; //final[w]=1表示求得顶点v0到vw的最短路径
for(v=0;v<G.numVertexes;++v)
{
final[v]=0;
(*D)[v]=G.arc[v0][v];
(*P)[v]=0;
}
final[v0]=1; //v0到v0不需要求路径
for(v=1;v<G.numVertexes;++v)
{
min=INFINITY;
for(w=0;w<G.numVertexes;++w)
{
if(!final[w] && (*D)[w]<min)
{
k=w;
min=(*D)[w]; //w(或k)顶点离V0顶点更近
}
}
final[k]=1; //将目前找到的最近的顶点置为1
for(w=0;w<G.numVertexes;w++)
{ //如果经过k顶点的路径比现在这条路径长度短的话
if(!final[w] && (min+G.arc[k][w]<(*D)[w]))
{
(*D)[w]=min+G.arc[k][w]; //修改当前路径长度
(*P)[w]=k; //记录目前最短路径的前驱顶点
}
}
}
}
void main(void)
{
int i,j,k[9];
MGraph G= //顶点数和权值表(行下标对应顶点到列下标对应顶点的边权值)
{
/*.numVertexes=*/9, //结构体初始化搞半天原来是VC不支持C99标准
/*.arc[9][9]=*/{0,1,5,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,
1,0,3,7,5,INFINITY,INFINITY,INFINITY,INFINITY,
5,3,0,INFINITY,1,7,INFINITY,INFINITY,INFINITY,
INFINITY,7,INFINITY,0,2,INFINITY,3,INFINITY,INFINITY,
INFINITY,5,1,2,0,3,6,9,INFINITY,
INFINITY,INFINITY,7,INFINITY,3,0,INFINITY,5,INFINITY,
INFINITY,INFINITY,INFINITY,3,6,INFINITY,0,2,7,
INFINITY,INFINITY,INFINITY,INFINITY,9,5,2,0,4,
INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,INFINITY,7,4,0,},
};
Pathmatirx P;
ShortPathTable D;
/*printf("Enter the number of Vertexes:");
scanf("%d",&G.numVertexes);
for(i=0;i<G.numVertexes;++i)
{
for(j=0;j<G.numVertexes;++j)
{
scanf("%d",&G.arc[i][j]);
}
}*/
dijkstra(G,0,&P,&D);
printf("P[]=");
for(i=0;i<MAXVEX;++i)
printf("%d ",P[i]);
printf("\n");
printf("D[]=");
for(i=0;i<MAXVEX;++i)
printf("%d ",D[i]);
printf("\n");
printf("输入要查找最短路径的目的顶点的下标:");
scanf("%d",&j);
printf("到此顶点最短路径的权:%d\n",D[j]);
k[0]=j;
for(i=1;i<9;++i)
{
k[i]=P[j];
if(P[j] == 0)
break;
j=P[j];
}
printf("最短路径:%d",k[i]);
while(i--)
{
printf("->%d",k[i]);
}
printf("\n");
}
算法的时间复杂度为O(n^2)。可以得到从v0到所有顶点的最短路径以及具体的路径。