Floyd算法的原理和实现代码

原理

假设有向图G=(V,E)采用邻接矩阵存储。设置一个二维数组A用于存放当前顶点之间的最短路径长度,分量A[i][j]表示当前顶点i -> j的最短路径长度。然后,每次添加一个顶点,同时对A的数组进行筛选优化,期间会产生k个A数组。Ak[i][j]数组代表着从考虑0 -> k的i -> j 的最小距离,当k 等于全部顶点数的时候,就是已经找出了i -> j 的最短距离。
在这里插入图片描述

初始化

在这里插入图片描述

1. 二维数组 path [i] [j] 初始化时,i -> j有路径时,path [i] [j] = i (即指向j的前一个顶点位置); 没有路径时path [i] [j] 初始化为-1

2.二维数组A[i][j] 初始化时就等价于边 i -> j 的权值。

算法过程

  1. 用二维数组A存储最短路径长度:

    • Ak[i][j]表示考虑顶点0~k后得出的i -> j的最短路径长度。
    • An-1[i][j]表示最终的i -> j的最短路径长度。
  2. 用二维数组path存放最短路径:

    • pathk[i][j]表示考虑顶点0~k后得出的i -> j的最短路径。
    • pathn-1[i][j]表示最终i -> j的最短路径。

在这里插入图片描述
在这里插入图片描述

实际上就是从一个个顶点开始分析,从一个到多个的过程中去筛选。初始化数据后,开始添加节点1,再去分析如果包含了节点1以后的各点之间路径是不是有变短,如果有的话就替换,这一遍分析过程被称为二维数组A的更新,也就是Ak数组,k是分析的节点1。而我们的path数组则是用来存放路径,其实就是i->j的路径上的j的上一步的顶点。

3.路径的求解
在这里插入图片描述

实现

Floyd算法的C语言实现如下:

void Floyd(MatGraph g)	//求每对顶点之间的最短路径
{  int A[MAXVEX][MAXVEX];	//建立A数组
   int path[MAXVEX][MAXVEX];	//建立path数组
  int i, j, k;
  for (i=0;i<g.n;i++)   		
     for (j=0;j<g.n;j++) 
     {  A[i][j]=g.edges[i][j];
        if (i!=j && g.edges[i][j]<INF)
	    path[i][j]=i; 	//i和j顶点之间有一条边时
     else			//i和j顶点之间没有一条边时
	    path[i][j]=-1;
     }
     //以上是初始化过程内容
   for (k=0;k<g.n;k++)		//求Ak[i][j]
  {   for (i=0;i<g.n;i++)
       for (j=0;j<g.n;j++)
	    if (A[i][j]>A[i][k]+A[k][j])	//找到更短路径
	    {   A[i][j]=A[i][k]+A[k][j];	//修改路径长度
	         path[i][j]=path[k][j]; 	//修改最短路径为经过顶点k
        }
  }
      DispathFloyd(g, A, path);
}	

//以下为输出最短路径的函数
void DispathFloyd(MatGraph g, int A[][MAXV], int path[][MAXV])
{
    int i, j, k, s;
    int apath[MAXV], d;

    for (i = 0; i < g.n; i++)
        for (j = 0; j < g.n; j++)
        {
            if (A[i][j] != INF && i != j)
            {
                printf("从%d到%d的路径是:", i, j);
                k = path[i][j];
                d = 0;
                apath[d] = j;
                while (k != -1 && k != i)
                {
                    d++;
                    apath[d] = k;
                    k = path[i][k];
                }
                d++;
                apath[d] = i;
                printf("%d", apath[d]);

                for (s = d - 1; s >= 0; s--)
                    printf(",%d", apath[s]);
                printf("\t路径长度为:%d\n", A[i][j]);
            }
        }
}

可以看出时间复杂度为O(n^3)

Enjoy

在这里插入图片描述

posted @ 2020-08-21 22:13    阅读(1582)  评论(0编辑  收藏  举报