网G的存储结构为邻接表,编写函数利用狄克斯特拉(Dijkstra))求图的单源最短路径: void Dijkstra(ALGraph g,int v); //求从v到其他顶点的最短路径
时间: 2024-03-07 14:46:35 浏览: 84
分支限界法求解单源最短路径.zip
好的,下面是代码实现:
```
#define MAXVEX 100 // 最大顶点数
#define INFINITY 65535 // 无穷大
typedef struct {
int vex[MAXVEX]; // 顶点表
int arc[MAXVEX][MAXVEX]; // 邻接矩阵,可看作边表
int numVertexes, numEdges; // 图中当前的顶点数和边数
} MGraph;
typedef struct {
int adjvex; // 邻接点域,存储该顶点对应的下标
int weight; // 存储权值
struct ArcNode *next; // 指向下一个结点
} ArcNode;
typedef struct {
char data; // 顶点信息
ArcNode *first; // 指向第一个结点
} VNode, AdjList[MAXVEX];
typedef struct {
AdjList vertices;
int vexnum, arcnum; // 图的当前顶点数和边数
} ALGraph;
// Dijkstra算法,v表示源点
void Dijkstra(ALGraph g, int v) {
int dist[MAXVEX]; // 存储源点到各个顶点的最短路径
int path[MAXVEX]; // 存储各个顶点的前驱结点
int visited[MAXVEX]; // 标记各个顶点是否已经找到最短路径
int i, j, k, min;
// 初始化
for (i = 0; i < g.vexnum; i++) {
dist[i] = g.vertices[v].data == g.vertices[i].data ? 0 : INFINITY; // 初始化源点到其他顶点的距离,源点到自己为0,其余为无穷大
path[i] = -1; // 初始化各个顶点的前驱结点为-1,表示没有前驱结点
visited[i] = 0; // 初始化各个顶点的最短路径没有找到
}
visited[v] = 1; // 源点已经找到最短路径
// 开始主循环,每次找到一个顶点的最短路径
for (i = 1; i < g.vexnum; i++) {
min = INFINITY; // 初始化最小距离为无穷大
for (j = 0; j < g.vexnum; j++) {
if (!visited[j] && dist[j] < min) { // 找到距离源点最近的顶点
min = dist[j];
k = j;
}
}
visited[k] = 1; // 标记该顶点已经找到最短路径
// 以k为中间点,更新源点到其他顶点的距离
for (j = 0; j < g.vexnum; j++) {
if (!visited[j] && g.vertices[k].first != NULL && g.vertices[k].first[j].weight < INFINITY && dist[k] + g.vertices[k].first[j].weight < dist[j]) {
// 如果j未被访问,且k与j之间有边,且源点到k的距离加上k到j的距离小于源点到j的距离
dist[j] = dist[k] + g.vertices[k].first[j].weight; // 更新距离
path[j] = k; // 记录前驱结点
}
}
}
// 输出最短路径
for (i = 0; i < g.vexnum; i++) {
if (i != v) { // 不输出源点到自己的路径
printf("v%d到v%d的最短路径为:%d", v, i, dist[i]);
printf("路径为:v%d", i);
j = i;
while (path[j] != -1) {
printf("<--v%d", path[j]);
j = path[j];
}
printf("\n");
}
}
}
```
这段代码中,我们首先对各个顶点进行初始化,然后以源点为起点,每次找到距离源点最近的顶点,并以该顶点为中间点,更新源点到其他顶点的距离,直到所有顶点都被访问过。最后输出源点到其他顶点的最短路径。
阅读全文