对于网图而言,最短路径指两顶点之间经过的边上权值和最少的路径,并且路径上的第一个顶点是源点,最后一个顶点是 终点。
迪杰斯特拉dijkstra算法:
其本质是一种贪婪算法
也是最经典的单源最短路径算法
假设源点是V1,终点是V8,求其最短路径。
我们先求V1到V2 V4 V3哪条路径最短,答案是到V2最短。由于V2与V4 V5连线,V2->V5=7 V2->V4=1 故选择V4
于是再求V1到V4的最短路径,V1->V2->V4=4, V1->V4=5
故V1->V2->V4是最短距离的路程
V4与V3 V6 V7连线(V5排除)而后再重复比较路径
算法简单来说就是:
一步一步地求出它们之间的顶点的最短路径,过程中是基于已经求出的最短路径的基础上,求得更远顶点的最短路径
算法代码如下:
#define MAX 9 //假设最大顶点数为9
#define INFINITY 65535
typedef int Path[MAX]; //存储最短路径顶点下标
typedef int ShortPath[MAX]; //存储到各点最短路径的权值和
/*求有向网G的V0顶点到其余顶点V的最短路径P[V]以及带权长度D[V]
P[V]的值为前驱顶点的下标,D[V]表示V0到V的最短路径长度和*/
/*需要使用邻接矩阵*/
void ShortesPath(MGraph G,int v0,Path *p,ShortPath *D) //v0定义为0
{
int v,w,k,min;
int final[MAX]; //标志数组,final[x]=1时表示已经求得V0到VX顶点的最短路径
/*初始化*/
for(v=0;v<G.numVertexes;v++)
{
final[v]=0; //均为0表示所有点都没有求得最短路径
(*D)[v]=G.arc[v0][v]; //将与V0点有连线的顶点加权值,即将第V0行的邻接矩阵数据读入到D数组
(*p)[v]=0; //p数组全为0,表示目前没有路径
}
(*D)[v0]=0; //V0到自身的权值和为0
final[v0]=1; //V0算是已经求得最短路径(此时只有v0本身)
/*开始主循环,每次求出V0到某个顶点V的最短路径*/
for(v=1;v<G.numVertexes;v++) //从1开始
{
min=INFINITY;
for(w=0;w<G.numVertexes;v++)
{
if(!final[w]&&(*D)[w]<min) //顶点未加入最短路径且权值小于无穷(即与V0存在连线)
{
k=w;
min=(*D)[w]; //w顶点离V0更近
}
}
final[k]=1; //表示已求得最短
/*重要循环*/
for(w=0;w<G.numVertexes;w++) //修正最短路径和距离
{
if(!final[w]&&(min+G.arc[k][w]<(*D)[w]))
{
(*D)[w]=min+G.arc[k][w];
(*p)[w]=k;
}
}
}
}
代码解析被系统吃掉了,暂时不愿意再打一遍了
简单来说重要循环的作用是在找到V0和V1的最短路径的基础上对与V1有连线的其他顶点的边上权值进行计算得到最小权值和
有空再详述
算法的时间复杂度:
由于嵌套循环的存在,时间复杂度为O(n²)。