目录
前言:引用的是李春葆老师的《数据结构教程》里面的内容,建模的时候用到了这个算法,现在巩固一下,理解的不是很透彻,有帮助的话可以参考一下,没有的话没事哈哈哈?
前言:引用的是李春葆老师的《数据结构教程》里面的内容,建模的时候用到了这个算法,现在巩固一下,理解的不是很透彻,有帮助的话可以参考一下,没有的话没事哈哈哈?
一、Floyd算法的理论分析
二、实例求解
为了更好理解,再讲解下书上的实例。
对于path矩阵的理解。
首先要将有向图转化为邻接矩阵,转化规则如图3,题目如图4,求解过程再往下看:
注意Path3[1][0]=2,而不是Path3[1][0]=3。虽然在加入3之后,从0到1的距离由之前的7变成了6,距离缩短, 但是Path3[1][0]表示的是从1到0,0的前一个点是2而不是3。如下所示:
三、代码实现
代码是教程里的。
第一个文件 名为:graph.h,它会被 mFloyd.cpp文件引用。
//文件名 graph.h
typedef int InfoType;
#define MAXV 100 //最大顶点个数
//以下定义邻接矩阵类型
typedef struct
{ int no; //顶点编号
InfoType info; //顶点其他信息
} VertexType; //顶点类型
typedef struct //图的定义
{ int edges[MAXV][MAXV]; //邻接矩阵
int vexnum,arcnum; //顶点数,弧数
VertexType vexs[MAXV]; //存放顶点信息
} MGraph; //图的邻接矩阵类型
//以下定义邻接表类型
typedef struct ANode //弧的结点结构类型
{ int adjvex; //该弧的终点位置
struct ANode *nextarc; //指向下一条弧的指针
InfoType info; //该弧的相关信息,这里用于存放权值
} ArcNode;
typedef int Vertex;
typedef struct Vnode //邻接表头结点的类型
{ Vertex data; //顶点信息
ArcNode *firstarc; //指向第一条弧
} VNode;
typedef VNode AdjList[MAXV]; //AdjList是邻接表类型
typedef struct
{ AdjList adjlist; //邻接表
int n,e; //图中顶点数n和边数e
} ALGraph; //图的邻接表类型
第二个文件 名为:mFloyd.cpp
//文件名:mFloyd.cpp
#include <stdio.h>
#define MAXV 100 //最大顶点个数
#define INF 32767 //用32767表示∞
#include "graph.h"
//extern void DispMat(MGraph g); //外部函数在algo8-1.c
void DispMat(MGraph g)
//输出邻接矩阵g
{
int i,j;
for (i=0;i<g.vexnum;i++)
{
for (j=0;j<g.vexnum;j++)
if (g.edges[i][j]==INF)
printf("%3s","∞");
else
printf("%3d",g.edges[i][j]);
printf("\n");
}
}
void ppath(int path[][MAXV],int i,int j)
{
int k;
k=path[i][j];
if (k==-1) return;
ppath(path,i,k);
printf("%d,",k);
ppath(path,k,j);
}
void DisPath(int A[][MAXV],int path[][MAXV],int n)
{
int i,j;
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (A[i][j]==INF)
{
if (i!=j)
printf("从%d到%d没有路径\n",i,j);
}
else
{
printf("从%d到%d路径为:",i,j);
printf("%d,",i);ppath(path,i,j);printf("%d",j);
printf("\t路径长度为:%d\n",A[i][j]);
}
}
void Floyd(MGraph g) //弗洛伊德算法从每对顶点之间的最短路径
{
int A[MAXV][MAXV],path[MAXV][MAXV];
int i,j,k,n=g.vexnum;
for (i=0;i<n;i++) //给A数组置初值
for (j=0;j<n;j++)
{
A[i][j]=g.edges[i][j];
path[i][j]=-1;
}
for (k=0;k<n;k++) //计算Ak
{
for (i=0;i<n;i++)
for (j=0;j<n;j++)
if (A[i][j]>(A[i][k]+A[k][j]))
{
A[i][j]=A[i][k]+A[k][j];
path[i][j]=k;
}
}
printf("\n输出最短路径:\n");
DisPath(A,path,n); //输出最短路径
}
int main()
{
int i,j,u=0;
MGraph g;
int A[MAXV][4] = {
{ 0,5,INF,7},
{ INF,0,4,2},
{ 3,3,0,2},
{ INF,INF,1,0},
};
g.vexnum = 4; g.arcnum = 8;
for (i=0;i<g.vexnum;i++)
for (j=0;j<g.vexnum;j++)
g.edges[i][j]=A[i][j];
printf("\n");
printf("有向图G的邻接矩阵:\n");
DispMat(g);
Floyd(g);
printf("\n");
return 0;
}
以后根据实际情况,只要对mFlyod.cpp的以下部分进行修改即可。
int A[MAXV][4] = {
{ 0,5,INF,7},
{ INF,0,4,2},
{ 3,3,0,2},
{ INF,INF,1,0},
};
g.vexnum = 4; g.arcnum = 8;//顶点数,弧数