数据结构.图.无向带权&邻接矩阵.最短路径Dijkstra算法

本文介绍了Dijkstra算法用于解决无向带权图中从特定顶点出发到其他顶点的最短路径问题。通过邻接矩阵表示图,算法逐步找到最短路径,并详细阐述了算法的原理、操作步骤和关键要点。在循环过程中,不断更新最短路径信息,最终得到所有顶点的最短路径。
摘要由CSDN通过智能技术生成
  • 图的应用实在很广,课堂所学实为皮毛
  • 考虑基于邻接矩阵的无向带权图,边的权值的典型意义就是路途的长度,从顶点u到顶点v的边权值为w,可以表示城市u到城市v之间路长为w。
  • 最短路径问题考虑的就是从某个顶点出发到其他任何一个顶点所经过的最短的路径。

Dijkstra迪杰斯特拉算法

  • 根据起点V0,最终得到的是一个从V0到其他顶点的路径按路径长度依次递增的次序产生最短路径,可知一共有(顶点总数-1)条路径,分别对应着V0到其他某一顶点的最短路径。
  • n为顶点总数。则有顶点集V[n],起点索引“iv0”,邻接矩阵G[n][n];引入辅助向量D[n],D[iv]表示当前从顶点”iv0”到”iv”的最短路径的长度;引入辅助向量Final[n],Final[iv]为true表示顶点“iv0”到“iv”的最短路径已经找到。
  • 循环次数为n-1次,依次递增地得到一条最短路径。如此描述着实难以理解,不知一下说明是否有帮助
Dijkstra最终得到的最短路径集 长度 经过的边集
iv0 -> v1 L1 E1
iv0 -> v2 L2 (大于l1) E2
iv0 -> vn-1 Ln-1 (最大) En-1

原理

  • 1)从“iv0”出发的最短路径集中最短的一条必然是可以从“iv0”出发只经过一条边(设为e)到达。假设存在一条经过m(m>1)条边的更短的路径,那么这条边上从“iv0”出发的第一条边(设为e0)必然比”e”要短,那么”e0”就是最短的只经过一条边的路径。也就是说表中的E1必然只有一条边。
  • 2)首次循环将D[i]赋值为G[iv0][i],表示从“iv0”直接到达顶点“i”的路径的长度(无路径则为ManInt表示无穷)。Final除“iv0”为true外其余均为false。
  • 3)则D[n]中((值最小)&&(Final为false))的顶点就是上表的“v1”,并将Final[v1]设为true表示从“iv0”到“v1”的最短路径已经找到了。
  • 4)下一步寻找v2,也就是最短路径集中第二短的路径。我们已经找到了最短路径集中最短的路径也就是从“iv0”到“v1”这条路径,那么从“iv0”到“v2”的最短路径只能是以下两种情况之一
    • 1、从“iv0”直接到达“v2”
    • 2、从”iv0”经过“v1”到达“v2”
    • 说明:假如存在(iv0)->(v’)->(v2)为最短路径集中第二短的路径,那么也就存在(iv0)->(v’)要比这条“第二短”的路径更短,但是比“第二短”的路径更短的路径只能是我们已经找到了的(iv0)->(v1),所以不存在所谓的(v’࿰
  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮您回答这个问题。 首先,我们需要了解一下 Dijkstra 算法Dijkstra 算法用于解决带权有向中单源最短路径问题,即从一个源点出发,到其他所有点的最短路径算法步骤如下: 1. 初始化:将源点加入已访问集合,其余点加入未访问集合,并将源点到各个点的距离初始化为无穷大。 2. 选取距离最短的点:从未访问集合中选取距离源点最近的点,并将其加入已访问集合。 3. 更新距离:更新源点到未访问集合中的点的距离。如果通过当前已访问的点到达该点的距离比源点直接到该点的距离更短,则更新该点的距离。 4. 重复执行第2步和第3步,直到所有点都被加入已访问集合。 现在,我们来看一下使用 C 语言实现 Dijkstra 算法的代码: ```c #include <stdio.h> #define MAX 100 // 定义最大顶点数 #define INF 0x3f3f3f3f // 定义无穷大 int graph[MAX][MAX]; // 有向邻接矩阵 int dist[MAX]; // 存储源点到各个顶点的最短距离 int visited[MAX]; // 标记顶点是否已经访问 void Dijkstra(int start, int n) { // 初始化 for (int i = 0; i < n; i++) { visited[i] = 0; dist[i] = graph[start][i]; } visited[start] = 1; dist[start] = 0; // 进行 n-1 次迭代 for (int i = 0; i < n-1; i++) { int min_dist = INF; int min_index = -1; // 选取距离最短的点 for (int j = 0; j < n; j++) { if (!visited[j] && dist[j] < min_dist) { min_dist = dist[j]; min_index = j; } } if (min_index == -1) { break; } visited[min_index] = 1; // 更新距离 for (int j = 0; j < n; j++) { if (!visited[j] && graph[min_index][j] != INF && dist[min_index] + graph[min_index][j] < dist[j]) { dist[j] = dist[min_index] + graph[min_index][j]; } } } } int main() { int n, start; printf("请输入顶点数:"); scanf("%d", &n); printf("请输入邻接矩阵:\n"); for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { scanf("%d", &graph[i][j]); if (graph[i][j] == -1) { graph[i][j] = INF; } } } printf("请输入起点编号:"); scanf("%d", &start); Dijkstra(start, n); printf("源点到各个顶点的最短距离为:\n"); for (int i = 0; i < n; i++) { printf("%d ", dist[i]); } printf("\n"); return 0; } ``` 在这个代码中,我们输入了有向邻接矩阵,并将 -1 视为无穷大。然后,我们输入起点编号,调用 Dijkstra 函数计算源点到各个顶点的最短距离,最后输出结果。 希望能对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值