在文章 数据结构算法之 Dijkstra 单源最短路径(原理部分)中,给出了 Dijkstra 算法求单源最短路径的图文步骤,本文将给出该算法的代码实现。
回顾一下 数据结构算法之 Dijkstra 单源最短路径(原理部分)中给出的 Dijkstra 算法的具体步骤:
dist[]
,用于存储源节点到各个节点的最短路径长度。初始时,将源节点的距离设为 0,与源节点直接相连的节点的距离设为边的权重,其他节点的距离设为无穷大。visited[]
,用于标记是否已经访问过该节点。初始时,将源节点标记为已访问,其他节点标记为未访问。dist[]
数组中,并将这个基准节点标记为已访问。
dist[]
数组中存储的就是源节点到其他所有节点的最短路径长度。步骤三中的「相邻」节点包括直接与源节点相邻、通过已访问的节点间接与源节点相邻这两大类。换句话说,也就是
dist[]
数组中只要不是无穷大,就与源节点直接或间接相邻。
1 | // 邻接矩阵 |
Graph
是图的邻接矩阵对应的结构体:
vexs
用于保存顶点的集合,vexnum
是顶点数量,edgenum
是边数;matrix
用于保存邻接点信息的二维数组,matrix[i][j]
表示顶点 vexs[i]
和顶点 vexs[j]
之间的边的权重,若 matrix[i][j] = INF
,则表示这两个顶点之间没有边(不是邻接点)。实际中,一般给出的信息都是哪两个顶点之间有边,边的权重是多少,所有我们给出一个结构体用于存储边的数据。
1 | // 边的结构体 |
在编码中,图结构体变量的数据将会从边结构体变量的数据中获取。
这里的顶点是字符型(而非整数型),所以需要获取字符型顶点对应的索引——它在顶点集合中的位置。这样,才方便后续将邻接点存储在图结构的成员 matrix
中。
1 | // 获取顶点在顶点集合中的索引 |
就像上面说的,图结构体变量的数据将会从边结构体变量的数据中获取。所以,我们在这里实现了从给定的边数据来初始化图数据。
1 | // 构建图 |
对于无向图,要多加一行代码
pGraph->matrix[end][start] = pGraph->matrix[start][end]
哦。
1 | // Dijkstra 算法,找到源顶点到各顶点的最短路径 |
一次遍历可以访问一个顶点,源节点在初始化时被访问;所以,遍历 N-1 次后,所有顶点就都被访问过了。
1 | // 打印给定起点和终点的最短路径 |
1 |
|
一个数加上无穷大会溢出,所以定义的 INF 为最大值的一半,防止溢出风险。
这是测试用例中构建的图:
测试结果,打印从起点到终点的最短路径上的节点和最短距离:
1 | A -> A: A, minDist: 0 |
参考资料: