迪杰斯特拉算法处理无向图中最短路径的(dijkstra)Java实现(指定两点,求最短距离及路径)

这是一个Java程序,使用迪杰斯特拉算法来找到无向图中任意两点间的最短路径并输出路径。程序首先初始化起点到各点的最短距离,然后不断更新并寻找最近的未标记点,直到所有点都被访问过。最后通过getRoute函数输出从起点到所有点的路径。
摘要由CSDN通过智能技术生成



其实不是原创哈,我写不出来。


      如何求图中V0到V5的最短路径呢?
        java实现的方式如下: 
       第一步,根据图来建立权值矩阵:
       int[][] W = { 
    {  0,   1,   4,  -1,  -1,  -1 },
    {  1,   0,   2,   7,    5,  -1 },
    {  4,   2,   0,  -1,    1,  -1 }, 
    { -1,  7,  -1,   0,    3,    2 },
    { -1,  5,    1,   3,   0,    6 }, 
    { -1, -1,  -1,   2,   6,    0 } };(-1表示两边不相邻,权值无限大)
例如:W[0][2]=4 表示点V0到点V2的权值为4
W[0][3]=-1表示点V0与V3不相邻,所以权值无限大。
第二步:对V0标号;V0到其它点的路径得到 distance: {0,1,4,-1,-1,-1}; 找到V0到各点中权值最小的那个点(标号的点除外,-1代表无限大),故得到1即对应的下标1,得到V1;对V1标号,然后更改V0通过V1到其它点的路径得到 distance: { 0, 1, 3, 8, 6, -1}; 
第三步:找到distance中权值最小的那个点,(标号的点除外)得到V2,对V2标号,然后更改V0通过V1->V2到其它点的路径得到 distance: { 0, 1, 3, 8, 4, -1}; 
第四步:找到distance中权值最小的那个点,(标号的点除外)得到V4,对V4标号,然后更改V0通过V1->V2到其它点的路径得到 distance: { 0, 1, 3, 7, 4, 10}; 
第四步:找到distance中权值最小的那个点,(标号的点除外)得到V3,对V3标号,然后更改V0通过V1->V2到其它点的路径得到 distance: { 0, 1, 3, 7, 4, 9}; 
最后只剩下V5没有被标号,就找到V5了。结束!
源代码如下:




package reverse;


//这个算法用来解决无向图中任意两点的最短路径,同时输出路径(起点到所有点的)
public class Success_SQ {

public static String dijkstra(int[][] W1, int start, int end) {

System.out.println("起点:" + start + "终点:" + end);
boolean[] isLabel = new boolean[W1[0].length];// 是否标号
int[]

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
下面是使用 Dijkstra 算法解加权无向图任意两点最短路径及其最短值的 C 语言代码: ```c #include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <limits.h> #define MAXVEX 100 // 最大顶点数 #define MAXWEIGHT INT_MAX // 最大权重值 typedef struct { int vertex[MAXVEX]; // 顶点表 int edge[MAXVEX][MAXVEX]; // 邻接矩阵 int num_vex, num_edge; // 图的当前顶点数和边数 } AdjMatrix; void createGraph(AdjMatrix *G) { int i, j, k, weight; printf("请输入顶点数和边数: "); scanf("%d%d", &G->num_vex, &G->num_edge); getchar(); // 读取回车符 printf("请输入顶点信息: "); for (i = 0; i < G->num_vex; i++) { scanf("%d", &G->vertex[i]); } getchar(); // 读取回车符 for (i = 0; i < G->num_vex; i++) { for (j = 0; j < G->num_vex; j++) { G->edge[i][j] = MAXWEIGHT; // 初始化邻接矩阵 } } printf("请输入边信息(格式为: 起点 终点 权重):\n"); for (k = 0; k < G->num_edge; k++) { scanf("%d%d%d", &i, &j, &weight); G->edge[i][j] = weight; G->edge[j][i] = weight; // 无向图的邻接矩阵是对称的 } } void printGraph(AdjMatrix *G) { int i, j; printf("顶点信息如下:\n"); for (i = 0; i < G->num_vex; i++) { printf("%d ", G->vertex[i]); } printf("\n邻接矩阵信息如下:\n"); for (i = 0; i < G->num_vex; i++) { for (j = 0; j < G->num_vex; j++) { if (G->edge[i][j] == MAXWEIGHT) { printf("∞ "); } else { printf("%d ", G->edge[i][j]); } } printf("\n"); } } void Dijkstra(AdjMatrix *G, int start, int *dist, int *path) { bool visited[MAXVEX] = {false}; int i, j, k, min_dist; for (i = 0; i < G->num_vex; i++) { dist[i] = G->edge[start][i]; visited[i] = false; if (dist[i] == MAXWEIGHT) { path[i] = -1; } else { path[i] = start; } } dist[start] = 0; visited[start] = true; for (i = 1; i < G->num_vex; i++) { min_dist = MAXWEIGHT; for (j = 0; j < G->num_vex; j++) { if (!visited[j] && dist[j] < min_dist) { k = j; min_dist = dist[j]; } } visited[k] = true; for (j = 0; j < G->num_vex; j++) { if (!visited[j] && (min_dist + G->edge[k][j]) < dist[j]) { dist[j] = min_dist + G->edge[k][j]; path[j] = k; } } } } void printPath(AdjMatrix *G, int start, int *dist, int *path) { int i, j, k; for (i = 0; i < G->num_vex; i++) { if (i != start) { printf("从顶点 %d 到顶点 %d 的最短路径为: ", start, i); printf("%d", i); j = i; while (path[j] != start) { printf("<--%d", path[j]); j = path[j]; } printf("<--%d", start); printf(", 最短距离为: %d\n", dist[i]); } } } int main() { AdjMatrix G; int start, dist[MAXVEX], path[MAXVEX]; createGraph(&G); printGraph(&G); printf("请输入起始顶点: "); scanf("%d", &start); Dijkstra(&G, start, dist, path); printPath(&G, start, dist, path); return 0; } ``` 在该示例代码,我们定义了一个结构体 `AdjMatrix`,其包含了顶点表和邻接矩阵。函数 `createGraph` 用来创建图,函数 `printGraph` 用来输出图的信息。在最短路径的过程,我们使用了 Dijkstra 算法,其 `Dijkstra` 函数用来计算从起始顶点到其他顶点的最短路径和最短距离,`printPath` 函数用来输出最短路径和最短距离。 需要注意的是,在初始化邻接矩阵时,我们将所有边的权重初始化为最大值,表示无穷大。在算法实现,如果两个顶点之间没有边相连,则它们之间的距离也被认为是无穷大。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值