Floyd算法、Dijkstra算法最短路径问题(C语言)
问题
给定一个已知各边权重的有向图,现要求指定点到图中各点的最短距离。
解析
Floyd算法
假设采用矩阵存储图中各点到其余点的距离,Floyd算法的核心就是遍历其他点,看看直接从选中点直接到目标点的距离是否比从选中点途径其他点再到目标点的距离长,如果是的话就更新选中点对应的举证位置的值。
Floyd算法的核心是:
if(graph[i][j]>graph[i][k]+graph[k][j]){
graph[i][j] = graph[i][k]+graph[k][j];
}
设计
Floy
初始化图,使用二维数组graph->G[graph->nv][graph->nv]存放图中各点到其余点的距离,使用三个for循环对二维数组进行遍历,逐个尝试看通过当前点是否是比直接从选中点到目标点短的点,是的话就更新该位置的值。
核心代码:
for (int k = 0; k < graph->nv; ++k) {
for (int i = 0; i < graph->nv; ++i) {
for (int j = 0; j < graph->nv; ++j) {
if (T[i][j]>(T[i][k]+T[k][j])){
T[i][j] = T[i][k]+T[k][j];
}
}
}
}
Dijkstra
Dijkstra算法用两个数组实现分别为minlengt[graph->nv],temp[graph->nv]一个数组用来记录当前已经被选中过的点,另一个数组用来存放当前已有点组成的图到还没有选中的点的距离。每次从temp[]数组中选取距离最小的点加入到minlengt[]数组中,同时将此点从temp数组中删除(更改索引位置所对值为0),然后依据Floyd类似的原理(graph[i][j] = graph[i][k]+graph[k][j];)对temp数组进行更新。
核心代码:
for (int i = 0; i < graph2->nv; ++i) {
temp[i] = graph2->G[origin][i];
}
temp[origin] = 0;
for (int i = 1; i < graph2->nv; ++i) {
min = MAXLENGTH;
for (int o = 0; o < graph2->nv; ++o) {
if (!minLength[o]&&temp[o]<min){
min = temp[o];
k = o;
}
}
minLength[k] = 1;
for (int j = 0; j < graph2->nv; ++j) {
if (!minLength[j]){
if (min+graph2->G[k][j]<temp[j]){
temp[j] = min+graph2->G[k][j];
}
}
}
}
分析
时间复杂度:
- Floyd算法:O(n3)
- Dijkstra算法:O(n2+2n)