目录
适用条件
基本操作函数
功能实现函数
测试使用图
算法讲解
初始化
迭代
弗洛伊德算法代码
全部代码
实验结果
最短路径算法比较
图中可以有负权,但不能有负圈(圈中弧或边的权值之和小于0)
表格行为i,列为j。D及P后小括号内的值为迭代次数。
D矩阵主对角线为0,其余与邻接矩阵相同。
P矩阵存-1,在输出最短路径时作为递归出口。
D矩阵的状态转移方程:D(m)[i][j]=min{D(m-1)[i][j],D(m-1)[i][k]+D[k][j]},0< 思路:添加一个点Vk,找到Vk的入弧Vi->Vk,再找到Vk的出弧,Vk->Vj,比较D[i][j]与D[i][k]+D[k][j]的大小。 若D矩阵有更新,则对应P矩阵的值为更新处最短路径第一条弧的终点。 D(1) P(1) D(2) 加入点V0,V0的入弧有V1->V0与V3->V0,出弧有V0->V1与V0->V2。 经比较D(1)[3][2]>D(1)[3][0]+D(1)[0][2],6>5-3=2,所以,将6更新为2。 P(2) P(2)[3][2]由P(1)[3][2]改为0,因为最短路径为V3->V0->V2,第一条弧的终点为V0。 D(3) 0 加入点V1,V1入弧有V0->V1,V2->V1以及V3->V1,出弧有V1->V2,V1->V0。 经比较,D(2)[2][0]>D(2)[2][1]+D(2)[1][0],∞>10-3=7,所以,将∞更新为7。 D(2)[3][0]>D(1)[3][1]+D(2)[1][0],5>6-3=3,所以,将5更新为3。 D(2)[3][2]>D(1)[3][1]+D(2)[1][2],2>6-7=-1,所以,将2更新为-1。 P(3) P(3)[2][0]改为1,因为最短路径为V2->V1->V0,第一条弧的终点为V1。 P(3)[3][0]改为1,因为最短路径为V3->V1->V0,第一条弧的终点为V1。 P(3)[3][2]改为1,因为最短路径为V3->V1->V2,第一条弧的终点为V1。 下面的由读者根据原理及矩阵自己补充,加深印象。 D(4) 0 P(4) D(5) 0 P(5) 注意:弗洛伊德算法的最短路径在输出时不是倒着的,我们记录的是第一条弧的终点。例如,p[2][0]=3,P[3][0]=1,P[1][0]=-1, 则V[2]到V[0]的最短路径为2->3->1->0,值为6。也就是看P矩阵的列,这是与前面两篇最短路径算法不同的地方,需注意。 O(v^3) 更多数据结构与算法实现:数据结构(严蔚敏版)与算法的实现(含全部代码) 有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。
0
4
-3
∞
-3
0
-7
∞
∞
10
0
3
5
6
6
0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
0
4
-3
∞
-3
0
-7
∞
∞
10
0
3
5
6
2
0
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
-1
0
-1
0
4
-3
∞
-3
0
-7
∞
7
10
0
3
3
6
-1
-1
-1
-1
-1
-1
-1
-1
-1
1
-1
-1
-1
1
-1
1
-1
0
4
-3
0
-3
0
-7
-4
7
10
0
3
3
6
-1
-1
-1
-1
2
-1
-1
-1
2
1
-1
-1
-1
1
-1
1
-1
0
4
-3
0
-3
0
-7
-4
6
9
0
3
3
6
-1
-1
-1
-1
2
-1
-1
-1
2
3
3
-1
-1
1
-1
1
-1
弗洛伊德算法代码
//最短路径 - Floyd_Wallshall算法 参数:图G 作用:计算不含负圈图的最短路径 返回是否有圈
bool Floyd_Wallshall(Graph G)
{
//初始化
for (int i = 0; i
全部代码
/*
Project: 图-最短路径-Bellman-Ford算法(可含有负权弧)
Date: 2019/10/24
Author: Frank Yu
基本操作函数:
InitGraph(Graph &G) 初始化函数 参数:图G 作用:初始化图的顶点表,邻接矩阵等
InsertNode(Graph &G,VexType v) 插入点函数 参数:图G,顶点v 作用:在图G中插入顶点v,即改变顶点表
InsertEdge(Graph &G,VexType v,VexType w) 插入弧函数 参数:图G,某弧两端点v和w 作用:在图G两点v,w之间加入弧,即改变邻接矩阵
Adjancent(Graph G,VexType v,VexType w) 判断是否存在弧(v,w)函数 参数:图G,某弧两端点v和w 作用:判断是否存在弧(v,w)
BFS(Graph G, int start) 广度遍历函数 参数:图G,开始结点下标start 作用:宽度遍历
DFS(Graph G, int start) 深度遍历函数(递归形式)参数:图G,开始结点下标start 作用:深度遍历
Dijkstra(Graph G, int v) 最短路径 - Dijkstra算法 参数:图G、源点v
Bellman_Ford(Graph G, int v) 最短路径 - Bellman_Ford算法 参数:图G、源点v 作用:计算不含负圈图的最短路径 返回是否有圈
Floyd_Wallshall(Graph G) 最短路径 - Floyd_Wallshall算法 参数:图G 作用:计算不含负圈图的最短路径 返回是否有圈
功能实现函数:
CreateGraph(Graph &G) 创建图功能实现函数 参数:图G InsertNode 作用:创建图
BFSTraverse(Graph G) 广度遍历功能实现函数 参数:图G 作用:宽度遍历
DFSTraverse(Graph G) 深度遍历功能实现函数 参数:图G 作用:深度遍历
Shortest_Dijkstra(Graph &G) 调用最短路径-Dijkstra算法 参数:图G、源点v
Shortest_Bellman_Ford(Graph &G) 调用最短路径- - Bellman_Ford算法 参数:图G
Shortest_Floyd_Wallshall(Graph &G) 调用最短路径- - Floyd_Wallshall算法 参数:图G
*/
#include
#include
实验结果
最短路径算法比较
算法\比较内容
适用条件
算法思想
时间复杂度
Dijkstra
无负权的图,单源或多源
贪心
O(v^2)、O(v^3)
Bellman-Ford
可以有负权但无负圈的图
动态规划
O(v^3)、O(ve)
Floyd-Warshall
无负权的图,多源
动态规划