用c语言实现并给出详细注释【问题描述】最短路径问题实际上是带权有向图(网)的一种应用,用Dijkstra算法求两个顶点间的最短路径。备注:输入的有向网信息中0表示不存在顶点到自身的弧,32767表示两个顶点之间不存在弧。 【输入形式】带权有向图(网)的顶点数及,有向图(网)的信息,出发顶点。 【输出形式】输出出发顶点到有向图(网)其余顶点间的最短路径长度及其路径。
时间: 2024-02-16 21:00:17 浏览: 60
好的,以下是一份用C语言实现Dijkstra算法求解最短路径问题的代码,已给出详细注释:
```c
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAX_VERTEX_NUM 100 // 最大顶点数
#define INF 32767 // 定义极大值
// 定义边结构体
typedef struct ArcNode {
int adjvex; // 该边指向的顶点
int weight; // 边的权重
struct ArcNode* next; // 指向下一条边的指针
} ArcNode;
// 定义顶点结构体
typedef struct {
int data; // 顶点信息
ArcNode* firstArc; // 指向第一条边的指针
} VNode;
// 定义邻接表结构体
typedef struct {
VNode adjList[MAX_VERTEX_NUM]; // 邻接表数组
int vexNum, arcNum; // 顶点数和边数
} ALGraph;
// 初始化邻接表
void InitGraph(ALGraph* G, int n) {
G->vexNum = n;
G->arcNum = 0;
for (int i = 0; i < G->vexNum; i++) {
G->adjList[i].data = i; // 以顶点编号作为顶点信息
G->adjList[i].firstArc = NULL; // 初始化指向第一条边的指针为空指针
}
}
// 添加边
void AddArc(ALGraph* G, int u, int v, int w) {
// u和v分别是边的起点和终点,w是边的权重
ArcNode* arc = (ArcNode*)malloc(sizeof(ArcNode));
arc->adjvex = v;
arc->weight = w;
arc->next = G->adjList[u].firstArc;
G->adjList[u].firstArc = arc;
G->arcNum++;
}
// Dijkstra算法求解最短路径
void Dijkstra(ALGraph* G, int s, int* dist, int* path) {
int visited[MAX_VERTEX_NUM] = {0}; // 标记数组,用来记录每个顶点是否已被访问
for (int i = 0; i < G->vexNum; i++) {
dist[i] = INF; // 初始化距离数组
path[i] = -1; // 初始化路径数组
}
dist[s] = 0; // 出发点到自身的距离为0
// Dijkstra算法主体
for (int i = 0; i < G->vexNum; i++) {
int minDist = INF;
int u = -1;
// 找到当前未访问的节点中距离最小的节点
for (int j = 0; j < G->vexNum; j++) {
if (!visited[j] && dist[j] < minDist) {
minDist = dist[j];
u = j;
}
}
// 标记当前节点为已访问
visited[u] = 1;
// 更新与当前节点相邻节点的距离
ArcNode* arc = G->adjList[u].firstArc;
while (arc != NULL) {
int v = arc->adjvex;
if (!visited[v] && dist[u] + arc->weight < dist[v]) {
dist[v] = dist[u] + arc->weight;
path[v] = u;
}
arc = arc->next;
}
}
}
int main() {
ALGraph G;
int n, s;
printf("请输入顶点数:");
scanf("%d", &n);
InitGraph(&G, n);
printf("请输入有向图的信息(用空格分隔,行末不需要空格):\n");
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int w;
scanf("%d", &w);
if (w != 0 && w != INF) {
AddArc(&G, i, j, w);
}
}
}
printf("请输入出发顶点:");
scanf("%d", &s);
int dist[MAX_VERTEX_NUM] = {0}; // 存储最短路径长度的数组
int path[MAX_VERTEX_NUM] = {0}; // 存储路径的数组
Dijkstra(&G, s, dist, path);
// 输出结果
for (int i = 0; i < G.vexNum; i++) {
if (i != s) {
printf("从顶点%d到顶点%d的最短路径长度为:%d\n", s, i, dist[i]);
printf("路径为:");
int p = i;
while (p != -1) {
printf("%d", p);
p = path[p];
if (p != -1) {
printf("->");
}
}
printf("\n");
}
}
return 0;
}
```
你可以将这份代码复制到本地,然后编译运行。输入格式请按照题目要求输入,输出格式也需要与题目要求一致。
阅读全文