2025/12/23

C 语言实现迪杰斯特拉算法求解有向网最短路径的代码:
代码实现
c
运行

include <stdio.h>

include <string.h>

include <limits.h>

define MAX_VEX 100 // 最大顶点数

define INF INT_MAX // 表示无穷大

// 图的邻接矩阵存储结构
typedef struct {
char vexs[MAX_VEX][10]; // 顶点值(支持字符串形式)
int arcs[MAX_VEX][MAX_VEX]; // 邻接矩阵,存储边权
int vex_num; // 顶点数
int arc_num; // 边数
} Graph;

// 查找顶点在图中的索引
int find_vex_index(Graph *G, char *vex) {
for (int i = 0; i < G->vex_num; i++) {
if (strcmp(G->vexs[i], vex) == 0) {
return i;
}
}
return -1; // 未找到
}

// 迪杰斯特拉算法求最短路径
void dijkstra(Graph *G, int start_idx, int end_idx, int *dist, int *path) {
int visited[MAX_VEX] = {0}; // 标记顶点是否已确定最短路径
int i, j, min, u;

// 初始化dist和path
for (i = 0; i < G->vex_num; i++) {
    dist[i] = G->arcs[start_idx][i];
    path[i] = (dist[i] != INF) ? start_idx : -1;
}
dist[start_idx] = 0;
visited[start_idx] = 1;

// 迭代n-1次(确定其余顶点的最短路径)
for (i = 1; i < G->vex_num; i++) {
    min = INF;
    u = -1;
    // 找到当前未确定最短路径的顶点中,dist最小的顶点u
    for (j = 0; j < G->vex_num; j++) {
        if (!visited[j] && dist[j] < min) {
            min = dist[j];
            u = j;
        }
    }
    if (u == -1) break;  // 无可达顶点,提前结束
    visited[u] = 1;

    // 松弛操作:更新以u为中介的顶点的dist和path
    for (j = 0; j < G->vex_num; j++) {
        if (!visited[j] && G->arcs[u][j] != INF && dist[u] + G->arcs[u][j] < dist[j]) {
            dist[j] = dist[u] + G->arcs[u][j];
            path[j] = u;
        }
    }
}

}

// 递归回溯输出最短路径
void print_path(Graph *G, int *path, int start_idx, int end_idx) {
if (start_idx == end_idx) {
printf("%s", G->vexs[start_idx]);
return;
}
if (path[end_idx] == -1) {
printf("无路径");
return;
}
print_path(G, path, start_idx, path[end_idx]);
printf("-->%s", G->vexs[end_idx]);
}

int main() {
Graph G;
char start_vex[10], end_vex[10];
int dist[MAX_VEX], path[MAX_VEX];
int i, j;

// 初始化邻接矩阵为无穷大
for (i = 0; i < MAX_VEX; i++) {
    for (j = 0; j < MAX_VEX; j++) {
        G.arcs[i][j] = INF;
    }
}

// 输入顶点数和边数
scanf("%d %d", &G.vex_num, &G.arc_num);

// 输入顶点值
for (i = 0; i < G.vex_num; i++) {
    scanf("%s", G.vexs[i]);
}

// 输入边的信息(起点、终点、权值)
for (i = 0; i < G.arc_num; i++) {
    char v1[10], v2[10];
    int weight;
    scanf("%s %s %d", v1, v2, &weight);
    int idx1 = find_vex_index(&G, v1);
    int idx2 = find_vex_index(&G, v2);
    G.arcs[idx1][idx2] = weight;  // 有向网,仅存一条边
}

// 输入要求路径的两个顶点
scanf("%s %s", start_vex, end_vex);
int start_idx = find_vex_index(&G, start_vex);
int end_idx = find_vex_index(&G, end_vex);

// 执行迪杰斯特拉算法
dijkstra(&G, start_idx, end_idx, dist, path);

// 输出最短路径
print_path(&G, path, start_idx, end_idx);
printf("\n");

return 0;

}
代码说明
图的存储:使用邻接矩阵存储有向网,顶点值用字符串数组存储(支持任意字符形式的顶点)。
迪杰斯特拉算法核心:
用dist数组存储起点到各顶点的最短距离;
用path数组存储最短路径的前驱顶点(用于回溯路径);
每次迭代找到 “未确定最短路径且距离最小” 的顶点,通过松弛操作更新其他顶点的距离和前驱。
路径输出:通过递归回溯path数组,从终点反向追溯到起点,再正向输出路径。
测试(输入样例)
输入:
plaintext
6 8
0 1 2 3 4 5
0 2 10
0 4 30
0 5 100
1 2 5
2 3 50
3 5 10
4 3 20
4 5 60
0 3
输出:
plaintext
0-->4-->3

posted on 2025-12-25 22:20  才一斤  阅读(2)  评论(0)    收藏  举报

导航