- 迪杰斯特拉算法:是一种典型的最短路径算法,用于计算一个结点到其他结点的最短路径,主要特点是以起始点为中心向外层层扩展(广度优先思想),直到扩展到终点。
算法思想:找到离源点最近的一个点,找到以该点为中心,找到源点到其他节点的最短路径。
举例详细分析
采用邻接矩阵存储图,顶点之间不可达记为无穷大,上图对角线也是无穷大。
计算顶点1的最短路径
1.首先定义一个dis数组,将1到其他顶点的的距离保存到数组里。
2.定义一个book数组,标记dis数组中的顶点是否被处理过。
3.在dis中寻找离源点距离最近的2号点,以2号点为源点,并将2号点标记,根据2号点到可达顶点的距离优化dis数组的距离。
2->3 :9 2->4 :3
1->2->:1+9 = 10 < 12更新,1->2->4:1+3=4 < 无穷大 更新
更新后的dis数组
4.在3和4中选择距离较小的4作为源点优化dis数组,将结点4标记
4->3 :4 4->5:13 4->6:15
1->4->3:4+4 = 8>10更新1->4->5:4+13=17 < 无穷大 更新
1->4->6:4+15 = 19 < 无穷大 更新
更新后的dis数组
5.dis中选择没有被标记且距离最短的顶点,3,以3为顶点优化dis数组并将3标记。
3->5:5
1->3->5:8+5=13<17更新,更新后的dis
6.继续从dis中选择没有访问且距离最短的点5,并将5标记,以5为源点优化dis数组。
5->6 :4,
1->5->6:13+7 = 17 < 19优化
优化后的dis
7.继续从dis中选择没有访问且距离最短的点6,并将6标记,以6为源点优化dis数组,发现6没有可达顶点此时dis数组中的所有点都经过处理了最终的dis为
也就是源点1到各个顶点的最短路径,整个过程我们已经掌握了下面我们来完成代码
vector<int> Dijkstra(const V& des)
{
vector<int> dis(_vertex.size(),0);
vector <int> book(_vertex.size(),0);
int index = GetIndexofVertex(des);
book[index] = 1;
for (size_t i = 0; i < _edge.size(); i++)
{
dis[i] = _edge[index][i];
}
while (true)
{
int idx = -1;
int min = INT_MAX;
for (size_t j = 0; j < dis.size(); j++)
{
if (book[j] == 0 && dis[j] < min)
{
idx = j;
min = dis[j];
}
}
if (idx == -1)
break;
book[idx] = 1;
for (size_t k = 0; k < dis.size(); k++)
{
if (_edge[idx][k] < INT_MAX)
{
if (dis[k] > dis[idx] + _edge[idx][k])
{
dis[k] = dis[idx] + _edge[idx][k];
}
}
}
}
return dis;
}