数据结构篇:校园最短路径导航(二:弗洛伊德算法理解与应用)

求最短路径最常用的有迪杰斯特拉(Dijkstra)和弗洛伊德(Floyd)算法两种。本着简洁为王道的信条,我选择了Floyd算法。

Floyd算法

首先来看一个简单图,红色标记代表在数组的下标,橙色标记代表距离(边权值)

我们用D[6][6]这个矩阵存储两点之间最短路径,用P[6][6]这个矩阵存储路径

两个矩阵初始化如下,若两点不直接联通,则初始化为无穷大

D[6][6]
 ABCDEF
A07105
B708
C8065
D607
E10704
F5540
P[6][6]
 ABCDEF
A012345
B012345
C012345
D012345
E012345
F012345

核心代码

    for (int k = 0; k < G->numVertexes; ++k)
    {
        for (int v = 0; v < G->numVertexes; ++v)
        {
            for (int w = 0; w < G->numVertexes; ++w)
            {
                if (D[v][w] > D[v][k] + D[k][w])
                {
                    D[v][w] = D[v][k] + D[k][w];
                    P[v][w] = P[v][k];
                }
            }
        }
    }

其中k为中转顶点下标,级无论走哪条路径,都要经过k下标的顶点,v代表起始顶点,w代表终点。 

当取k=0时代表所有路径都经过下标为0的地点(A)

  • v取2,w取3,即从C到D,有C-A-D,可惜这个路径的和不小于C-D的路径大小,所以D数组不会有变化。
  • v取1,w取4,即从B到E,有B-A-E,发现它的值为17,小于B-E的无穷大,所以D[1][4]由无穷大改为17,因为D数组变化了,所以P数组也要跟着变化,把P[1][4]改为当前P[1][0],代表从B到E下一节点为A
  • 同理在k取0时,将这个时间复杂度为O(6^2)的循环走完,那么D和P矩阵如下
D[6][6]
 ABCDEF
A07105
B7081712
C8065
D607
E1017704
F512540
P[6][6]
 ABCDEF
A012345
B012300
C012345
D012345
E002345
F002345

然后取k=1,2,3,4,5遍历完成后,D和P就是我们的目标数组了。

输出结果

这个就比较简单了,比如我输入1,4,代表我想知道从B走到E的最短路径,先输出最短路径为D[1][4]。然后就是具体的路径,我们找到P[1][4],发现它等于0,意味着从B走到E要先走B-A,然后我们看P[0][4],发现它等于4,也就是E,到达终点。

void AdjacencyList::ShowShortestResult(int originPos,int endPos) {
    int temp;
    cout << "地点" << _mapName[originPos] << "到地点" << _mapName[endPos] << "最短距离为" << ShortestPathvalue[originPos][endPos] << endl;
    temp = ShortestPathmatrix[originPos][endPos];
    cout<<"具体路径为:"<<_mapName[originPos]<<"——>";
    while (temp!=endPos){
        cout<<_mapName[temp]<<"——>";
        temp = ShortestPathmatrix[temp][endPos];
    }
    cout<<_mapName[endPos]<<endl;
}

 

  • 6
    点赞
  • 72
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值