一、最短路径的定义
在网图和非网图中,最短路径的含义是不同的。由于非网图没有边上的权值,所谓的最短路径,其实就是指两顶点之间经过的边数最少的路径;而对于网图来说,最短路径是指两顶点之间经过的边上权值之和最少的路径,并且称路径上的第一个顶点是源点,第二个顶点是终点。显然,非网图可以理解为所有的边的权值都为1的网图。
二、Dijkstra算法
1.Dijkstra算法描述
有向网中从源点V0到其他终点的最短路径的过程是:初始情况下,若从源点到该顶点有弧,则存在一条路径,路径长度即为该弧上的权值。每求得一条到达某个终点w的最短路径,就需要检查是否存在经过这个顶点w的其他路径(即是否存在从顶点w出发到尚未求得最短路径顶点的弧),若存在,判断其长度是否比当前求得的路径长度短,若是,则修改当前路径。同时,保存当前已得到的从源点到各个终点的最短路径。
2.Dijkstra算法的C语言代码实现
/* Dijkstra算法,求有向网G的v0顶点到其余顶点v的最短路径P[v]及带权长度D[v] */ /* P[v]的值为前驱顶点下标,D[v]表示v0到v的最短路径长度和 */ void ShortestPath_Dijkstra(MGraph G, int v0, Patharc *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];/* 将与v0点有连线的顶点加上权值 */ (*P)[v] = -1; /* 初始化路径数组P为-1 */ } (*D)[v0] = 0; /* v0至v0路径为0 */ final[v0] = 1; /* v0至v0不需要求路径 */ /* 开始主循环,每次求得v0到某个v顶点的最短路径 */ for(v=1; v<G.numVertexes; v++) { min=INFINITY; /* 当前所知离v0顶点的最近距离 */ for(w=0; w<G.numVertexes; w++) /* 寻找离v0最近的顶点 */ { if(!final[w] && (*D)[w]<min) { k=w; min = (*D)[w]; /* w顶点离v0顶点更近 */ } } final[k] = 1; /* 将目前找到的最近的顶点置为1 */ for(w=0; w<G.numVertexes; w++) /* 修正当前最短路径及距离 */ { /* 如果经过v顶点的路径比现在这条路径的长度短的话 */ if(!final[w] && (min+G.arc[k][w]<(*D)[w])) { /* 说明找到了更短的路径,修改D[w]和P[w] */ (*D)[w] = min + G.arc[k][w]; /* 修改当前路径长度 */ (*P)[w]=k; } } } }