JAVA编程求单源最短路径,[C++]单源最短路径:迪杰斯特拉(Dijkstra)算法(贪心算法)...

1 Dijkstra算法

1.1 算法基本信息

解决问题/提出背景

单源最短路径(在带权有向图中,求从某顶点到其余各顶点的最短路径)

算法思想

贪心算法

按路径长度递增的次序,依次产生最短路径的算法

【适用范围】Dijkstra算法仅适用于【权重为正】的图模型中

时间复杂度

O(n^3)

补充说明

亦可应用于【多源最短路径】(推荐:Floyd算法(动态规划,O(n^3)))

Dijkstra 时间复杂度:O(n^3)

1.2 算法描述

1.2.1 求解过程(具体思路)

caee7cf20c524bd4393b9f50e5ca4618.png

1.2.2 示例

70d406e0b88dd2cd8c3514253ee07094.png

1.2 编程复现

1> 定义图模型(邻接矩阵表示法)的【基本存储结构体】

# define MaxInt 32767 // 表示极大值 即 ∞ (无穷大)

# define MVNum 100 // 最大顶点数

typedef int VertexType; // 假设顶点的数据类型为整型

typedef int ArcType; // 假设Vi与Vj之边的权值类型为整型

typedef struct {

VertexType vexs[MVNum]; // 顶点表 (存储顶点信息)

ArcType arcs[MVNum][MVNum]; // 邻接矩阵

int vexnum,arcnum; // 图的当前顶点数与边数

}AMGraph; // Adjacent Matrix Graph 邻接矩阵图

2> 定义 Dijkstra 算法的【辅助数据结构体】

abeb9d71c114eb7fcda50a1e7bd374c6.png

bool S[MVNum]; // S[i] 记录从源点V0到终点Vi是否已被确定为最短路径长度 【划分确定与未确定: 跟贪心算法的适用范围(不可取消性)有直接联系】

// true:表已确定;false:表尚未确定

ArcType D[MVNum]; // D[i] 记录从源点V0到终点Vi的【当前】最短路径【长度】

int Path[MVNum]; // Path[i] 记录从源点V0到终点Vi的【当前】最短路径上【Vi的[直接前驱]的顶点序号】

3> 初始化(邻接矩阵)带权有向图的图模型

void InitAMGraph(AMGraph &G){

cout<

cin>>G.vexnum;

cout<

cin>>G.arcnum;

for(int i=0;i

for(int j=0;j

if(i!=j){ // 【易错】 初始化时: 路径长度无穷大 (i!=j)

G.arcs[i][j] = MaxInt;

} else { // 【易错】 初始化时: 【自回环】路径长度为0 (i==i)

G.arcs[i][j] = 0;

}

}

}

for(int i=0;i

G.vexs[i] = i;

}

cout<

cout<

int i,j;

int weight;

for(int k=0;k

//cout<

cin>>i;cin>>j;cin>>weight;

G.arcs[i][j] = weight;

}

cout<

}

4> Dijkstra算法:求解单源最短路径

void ShortestPath_Dijkstra(AMGraph G, int V0){

//step1 n个顶点依次初始化

int n =G.vexnum;

for(int v=0;v

S[v] = false;

D[v] = G.arcs[V0][v];

if(D[v]

Path[v] = V0;

} else {

Path[v] = -1;

}

}

//step2 将源点V0划入已确定集合S中

S[V0] = true;

D[V0] = 0; // 源点V0到源点V0的最短路径长度必然为0

//step3 贪心算法策略:

//3.1 循环遍历所有结点:

//3.2 先确定当前最短路径的终点v;

//3.3 然后,将v划入已确定集合S中;

//3.4 最后,以利用结点v更新所有尚未确定的结点的最短路径

int v;

int min;

D[G.vexnum] = MaxInt;

for(int i=1;i

//3.2 确定当前最短路径的终点v;

min = MaxInt;

for(int w=0;w

if(S[w]==false && D[w]

v = w;

min = D[w];

}

}

//3.3 然后,将v划入已确定集合S中;

S[v] = true;

//3.4 最后,以利用结点v更新所有尚未确定的结点的最短路径

for(int w=0;w

//↓更新Vw结点的最短路径长度为 D[v] + G.arcs[v][w]

//cout<

if(S[w]==false && (D[v] + G.arcs[v][w] < D[w])){//【易错/易漏】 S[w]==false : 必须满足当前结点 Vw 属于尚未确定的结点

D[w] = D[v] + G.arcs[v][w];

Path[w] = v; // 更新 结点Vw的前驱为 v

}

}

v = G.vexnum;

}

}

5> 输出结果 D[i]、Path[j]

void OutputD(AMGraph G, int V0){

cout<

for(int j=0;j

cout<

}

cout<

}

void OutputPath(AMGraph G,int V0){

cout<

for(int j=0;j

cout<

}

cout<

}

6> 执行:Main函数

int main(){

int V0; //源点V0的下标

AMGraph G;

InitAMGraph(G);

cout<

cin>>V0;

ShortestPath_Dijkstra(G, V0);

OutputD(G, V0);

OutputPath(G, V0);

return 0;

}

7> Test: Output of Main

ccbf68606d9ccc8b64acf48d4306e87c.png

Please Input Vertexs Number:6

Please Directed Edges Number:8

Please Input All Directed Edges and their Weight now:

Directed Edges(i,j,weight):

1 2 5

0 2 10

3 5 10

4 3 20

0 4 30

2 3 50

4 5 60

0 5 100

Please Input the Index of Source Node 'V0':0

Shortest Distance Weight of the Pair of Directed Vertices(0, j):

0 32767 10 50 30 60

Shortest Distance Path(0,j) of the Pair of Directed Vertices:

0 -1 0 4 0 3

2 参考文献

《数据结构(C语言版/ 严蔚敏 李冬梅 吴伟民 编)》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值