迪杰斯特拉算法是用于求解图的单元最短路径问题,即某个源点到达图中其余顶点的最短路径,其核心思想是每次从剩余未归入路径的顶点中找到一个到达当前路径距离最短的顶点,将其归入路径中,共执行n-1次。该算法需要三个辅助数组,s[ ]数组用来标记各个顶点有没有被归入当前路径中,dist[ ]数组用于表示当前源点到达各个顶点的最短路径长度,path[ ]数组用来存储该顶点在最短路径中的前驱结点。
#include<stdio.h>
//迪杰斯特拉算法,求带权图中某个源点到到达其余各个顶点的最短路劲,其需要三个辅助数组,s[i]=1表示
//该顶点已经求得最短路径,0表示未求得;dist[]数组用来存储当前源点到达各个顶点的最短路径;path[]
//数组存储源点到达该顶点的最短路径中其前驱结点
void Dijkstra(Mgraph G,int v,int dist[],int path[])
{
int[MAXSIZE];
int i,j,min,u;
//初始化各个数组
for(i = 0;i < G.vexnum;++i){
dist[i] = G.edges[v][i]; //dist[]初始时存储各个顶点到达源点的带权路径长度
s[i] = 0; //一开始各个顶点均未规划进入路径
if(dist[i] < 65535)
path[i] = v; //如果顶点与源点有弧,则该顶点的前驱结点为源点
else
path[i] = -1; //结点不存在前驱结点,path[i]设为-1
}
path[v] = -1; //源点不存在前驱结点,path[v]设为-1
s[v] = 1;
//关键步骤:1.从dist[]数组中找到当前剩余结点中到达路径距离最短的加入路径中并更新s[]数组
// 2.加入新节点后更新dist[]数组和path[]数组
for(i = 0;i < G.vexnum -1;++i){ // 执行n-1次,添加剩余的n-1个顶点
min = 65535;
for(j = 0;j < G.vexnum;++j){ //寻找dist[]数组中距离最小的顶点
if(s[j] == 0 && dist[j] < min){ //在未归入路径的顶点中寻找到达路径距离最短的顶点u
min = dist[j];
u = j;
}
}
s[u] = 1;
//更新dist[]和Ppath[]
for(j = 0;j < G.vexnum;++j){
if(s[j] == 0 && dist[j] > dist[u] + G.vexnum[u][j]){ //将未归入路径中的顶点的dist值与path值更新
dist[j] = dist[u] + G.vexnum[u][j];
path[j] = u;
}
}
}
}