最短路径算法—Floyd(弗洛伊德)算法

Floyd算法(解决任意两点间的最短路径,可以正确处理有向图或负权值的最短路径问题):

时间复杂度O(N3),空间复杂度O(N2);

算法思想:

Floyd算法是一个经典的动态规划算法;首先我们的目标是计算顶点i到j的最短路径,从动态规划角度来看:

从节点i到节点j的最短路径不外乎两种可能:1)直接从i到j; 2) i经过若干节点再到j;所以我们可以这样来计算i j之间的最短距离:对于每一个结点k,我们判断Dist(i,k)+Dist(k,j)Dist(i,k)+Dist(k,j); 这样,遍历完所有的k值,则得到最终从i到j的最小距离。

Floyd算法过程:

1、用D[i][j]记录每两个顶点之间的距离;

2、依次扫描每一个顶点k,以该点为基准,判断从i经过k,再到j的距离是否小于D[i][j],若是则更新D[i][j]=D[i][k]+D[k][j];

精髓:依次扫描每一点(k),并以该点作为中介点,计算出通过k点的其他任意两点(i,j)的最短距离,这就是floyd算法的精髓!同时也解释了为什么k点这个中介点要放在最外层循环的原因.

typedef struct
{
	char vertex[MAXVER];
	int edges[MAXVER][MAXVER];
	int n, e;
}MGraph;
void Floyd(MGraph g)
{
	int D[MAXVER][MAXVER];
	int path[MAXVER][MAXVER];
	int n = g.n;
	for (int i = 0; i < n; ++i) //初始化
	{
		for (int j = 0; j < n; ++j)
		{
			D[i][j] = g.edges[i][j];
			path[i][j] = -1;
		}
	}
	for (int k = 0; k < n; k++) //注意:一定要理解为什么把k放在最外层的循环,而不放在最内层!!
	{
		for (int i = 0; i < n; ++i)
		{
			for (int j = 0; j < n; ++j)
			{
				if (D[i][j]>D[i][k] + D[k][j])
				{
					D[i][j] = D[i][k] + D[k][j];
					path[i][j] = k;
				}
			}
		}
	}
}



你可能感兴趣的:(数据结构)