目录
迪杰斯特拉的用途
迪杰斯特拉算法用于求出图中一个结点到其他所有结点的最短路径。迪杰斯特拉算法是求最短路径中较为常用的算法,而且方便使用易于理解,很适合用来当成最短路径入门的模板实例算法。无论是在有向图还是无向图,都有它的优势之处。
迪杰斯特拉的思路
迪杰斯特拉算法的思路非常的清晰,我结合图解来解释(图是网上找的,如有雷同,纯属巧合)
先解释各个字母所代表的意思:S代表已经找到了最短路径的点,u代表目前的点到所连接的最短路径的点,dist储存目前起始点到该点的最短路径。(起始点为“1”)
逻辑主线
第一步:将与起始点直接连接的点的距离储存在dist数组中,找出到其中最短路径的点。如图中的点“2”,则10就是点“1”到点“2”的最短路径,因为从“1”经过其他点间接连接点“2”的点一定会比10 大(仔细想想就知道了)。
第二步:将(点“2”直接连接的点的距离 + 10)储存在dist数组中,如果原先数组中该点所在的位置已经有值,则比较,新值更小则替换。其中dist数组中值最小的点就是起始点到该点的最短距离,如图中sist[4]。
之后重复第二步的操作,直到将结点全部遍历。
注:每找出一个最短距离就将该点标记为一遍历,也就说需要(结点书-1)次循环
代码说明
/*迪杰斯特拉算法求某个顶点到其余顶点的最短路径*/
/*代码示例使用邻接矩阵来展示*/
void DIJ(MGraph &G, int v)
{
int i, j, k, min;
int final1[MAX_VERTEX_NUM];//该数组用来标识顶点是否已确定了最短路径
int dist[MAX_VERTEX_NUM];
string path[2 * MAX_VERTEX_NUM];
for (i = 0; i<G.vexnum; i++)
{//初始化工作
dist[i] = G.edges[v][i];//dist数组用来存储当前找到的v到其他各顶点的最短路径
if (dist[i]<MAX)
path[i] = G.vexs[v] + G.vexs[i];//如果v到i有边的话,把顶点字符存到path字符数组中,表示路径
else
path[i] = "";
final1[i] = 0;//初始化标识数组为0
}
dist[v] = 0;
final1[v] = 1;
for (j = 1; j<G.vexnum; j++)
{
min = MAX;
for (i = 0; i<G.vexnum; i++)
if (dist[i]<min && final1[i] == 0)
{
min = dist[i];
k = i;
}//找到dist数组中最小值的位置k
cout << path[k] << " " << dist[k] << endl;//输出最短路径
final1[k] = 1;//设置标志位
for (i = 0; i<G.vexnum; i++)
{//遍历每个顶点i和当前的已求出的最短路径的顶点k作比较,若从源点经过顶点k到顶点i的路径,比dist[i]小,
//则更新顶点dist[i]
if (dist[i]>dist[k] + G.edges[k][i] && final1[i] == 0)
{
dist[i] = dist[k] + G.edges[k][i];
path[i] = path[k] + G.vexs[i];
}
}//从整体上来看就是算出k的邻接点的当前最短路径
}
}
总结
迪杰斯特拉算法的便利性以及其思路的清晰性得到了很高的认可,属于数据结构中常用、也是ACM求最短路径的入门首选,需要我们去掌握。