弗洛依曼思想:只讲概念会显得空洞,下面我将结合一个算法实例来进行讲解
如下图,这是一个初始矩阵,矩阵的行表示左端结点,矩阵的列表示右端结点,矩阵的内容为相应的边的内容。
a[i][j] |
0 |
1 |
2 |
0 |
0 |
3 |
+& |
1 |
7 |
0 |
1 |
2 |
+& |
6 |
0 |
刚开始path数组全部初始化为-1
path[i][j] |
0 |
1 |
2 |
-1 |
-1 |
-1 |
-1 |
-1 |
-1 |
-1 |
-1 |
-1 |
-1 |
-1 |
-1 |
先以0作为遍历点
/*注意:由于a[0][0],a[0][1],a[0][2],a[1][0],a[2][0]都有结点0,故不放在比较里。
1. a[1][2]比较a[1][0]+a[0][2];由于a[1][2]较小,故路径不做改变
2. a[2][1]比较a[2][0]+a[2][1];由于a[2][1]较小,路径不做改变
接下来遍历结点1
1. a[0][2]比较a[0][1]a[1][2];由于a[0][2]
2. a[2][0]比较a[2][1]a[1][0];;由于a[2][0]
就得到了下图
a[i][j] |
0 |
1 |
2 |
0 |
0 |
3 |
4 |
1 |
7 |
0 |
1 |
2 |
13 |
6 |
0 |
path[i][j] |
0 |
1 |
2 |
-1 |
-1 |
-1 |
1 |
-1 |
-1 |
-1 |
-1 |
-1 |
1 |
-1 |
-1 |
接下来遍历最后一个结点2(用变化后的表格进行比较)
1. a[0][1]比较a[0][2]a[2][1];a[0][1]较小,故不变
2. a[1][0]比较a[1][2]a[2][0];a[1][0]=7,a[1][2]=1,a[2][0]=13,故a[1][0]较小,不改变
所以最终表格为
a[i][j] |
0 |
1 |
2 |
0 |
0 |
3 |
4 |
1 |
7 |
0 |
1 |
2 |
13 |
6 |
0 |
path[i][j] |
0 |
1 |
2 |
-1 |
-1 |
-1 |
1 |
-1 |
-1 |
-1 |
-1 |
-1 |
1 |
-1 |
-1 |
代码如下
void road(int a,int b,path[][max])
{
//从左到右,从下到上依次输出各结点
int v=path[a][b]
if(path[a][v]==-1)
printf("%d-->%d",a,v);
else
road(a,v,path);
if(path[v][j]==-1)
printf("%d-->%d",v,d);
else
road(v,d,path);
}
//对一个矩阵里面的各个结点间的距离,依次与各个结点作为中介的距离进行比
//较,即a[i][j] vs
//a[i][v]+a[v][j],如果a[i][j]比较大,则将a[i][j]的距离转换成a[i][v]+a[v
//][j],相应的path[i][j]数组的内容也变成v;
void less(ag a)
{
//初始path[]数组
for(i=0;i<a.n;i++)
{
path[i]=-1;
}
for(i=0;i<a.n;i++0)
for(j=0;j<a.n;j++)
for(k=0;k<a.n;k++)
{
if(j!=k&&a.a[j][k]<a.a[j][i]+a.a[i][k])
{
a.a[j][k]=a.a[j][i]+a.a[i][k];
path[j][k]=i;
}
}
}