狄杰斯特拉算法(Dijkstra Algorithm)是一种用于解决带权重图中单源最短路径问题的贪心算法。下面是一个用C语言实现的狄杰斯特拉算法,同时输出路径经过的节点。
```c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAX_VERTICES 1000
typedef struct {
int weight; // 边的权重
int dest; // 边的终点
int prev; // 前驱节点
} Edge;
typedef struct {
Edge edges[MAX_VERTICES][MAX_VERTICES];
int numVertices;
} Graph;
void init_graph(Graph *g, int n) {
g->numVertices = n;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
g->edges[i][j].weight = -1;
g->edges[i][j].dest = -1;
g->edges[i][j].prev = -1;
}
}
}
void add_edge(Graph *g, int src, int dest, int weight) {
g->edges[src][dest].weight = weight;
g->edges[src][dest].dest = dest;
}
void dijkstra_shortest_path(Graph *g, int src, int dest) {
int distance[MAX_VERTICES], visited[MAX_VERTICES];
for (int i = 0; i < g->numVertices; i++) {
distance[i] = INT_MAX;
visited[i] = 0;
}
distance[src] = 0;
int cur = src;
while (cur != dest) {
visited[cur] = 1;
for (int i = 0; i < g->numVertices; i++) {
if (g->edges[cur][i].weight != -1 && !visited[i]) {
int new_dist = distance[cur] + g->edges[cur][i].weight;
if (new_dist < distance[i]) {
distance[i] = new_dist;
g->edges[i][dest].prev = cur;
}
}
}
int shortest_dist = INT_MAX;
for (int i = 0; i < g->numVertices; i++) {
if (!visited[i] && distance[i] < shortest_dist) {
shortest_dist = distance[i];
cur = i;
}
}
if (shortest_dist == INT_MAX) {
printf("No path found!\n");
return;
}
}
printf("Shortest distance from %d to %d is %d\n", src, dest, distance[dest]);
printf("Path: %d", dest);
int node = dest;
while (node != src) {
node = g->edges[node][dest].prev;
printf("<-%d", node);
}
}
int main() {
Graph g;
init_graph(&g, 6);
add_edge(&g, 0, 1, 5);
add_edge(&g, 0, 2, 2);
add_edge(&g, 1, 2, 1);
add_edge(&g, 1, 3, 3);
add_edge(&g, 1, 4, 2);
add_edge(&g, 2, 1, 3);
add_edge(&g, 2, 4, 3);
add_edge(&g, 3, 5, 1);
add_edge(&g, 4, 3, 1);
add_edge(&g, 4, 5, 2);
dijkstra_shortest_path(&g, 0, 5);
return 0;
}
```
上述代码中,`init_graph`函数用于初始化图结构,`add_edge`函数用于向图中添加边。`dijkstra_shortest_path`函数是狄杰斯特拉算法的实现,主要思路是从源节点开始,不断找到与当前节点连接的距离最短的节点,更新距离信息。同时,每次更新距离信息时,记录下前驱节点,最终根据前驱节点信息逆向输出路径经过的节点。