用C语言写一段代码并且有注释,游客通过终端询问可知,要求:(1)将导游图看作一张带权无向图,顶点表示公园的各个景点,边表示各景点之间的道路,边上的权值表示距离,选择适当的数据结构。 (2)为游客提供图中任意景点相关信息的查询。 (3)为游客提供任意两个景点之间最短的简单路径。 (4)为游客选择最佳游览路径。(5)以邻接表为存储结构,利用Dijkstra算法或Floy算法求最短路径,利用搜索求最佳路径。(6)可在devc++运行
时间: 2024-02-05 10:14:17 浏览: 41
以下是基于邻接表存储结构,使用Dijkstra算法求最短路径的C语言代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_VERTEX_NUM 100 // 最大顶点数
#define INFINITY 65535 // 定义∞
#define MAX_NAME_LEN 20 // 顶点名称最大长度
// 边表结点
typedef struct ArcNode {
int adjvex; // 该边指向的顶点位置
int weight; // 边权值
struct ArcNode *next; // 指向下一个邻接点
} ArcNode;
// 顶点信息
typedef struct {
char name[MAX_NAME_LEN]; // 顶点名称
ArcNode *firstarc; // 第一个邻接点
} VNode;
// 邻接表
typedef struct {
VNode vexs[MAX_VERTEX_NUM]; // 顶点数组
int vexnum; // 顶点数
int arcnum; // 边数
} ALGraph;
// 创建邻接表图
void createGraph(ALGraph *G) {
printf("请输入公园中景点的数量:");
scanf("%d", &G->vexnum);
getchar(); // 消除输入缓冲区中的回车键
printf("请按照名称顺序输入每个景点的名称,每个名称不超过%d个字符:\n", MAX_NAME_LEN);
for (int i = 0; i < G->vexnum; i++) {
fgets(G->vexs[i].name, MAX_NAME_LEN, stdin);
G->vexs[i].name[strlen(G->vexs[i].name) - 1] = '\0'; // 去掉输入中的回车键
G->vexs[i].firstarc = NULL;
}
printf("请输入公园中道路的数量:");
scanf("%d", &G->arcnum);
for (int i = 0; i < G->arcnum; i++) {
char v1_name[MAX_NAME_LEN], v2_name[MAX_NAME_LEN];
int weight;
printf("请输入第%d条道路连接的两个景点的名称及其长度:", i + 1);
scanf("%s %s %d", v1_name, v2_name, &weight);
getchar(); // 消除输入缓冲区中的回车键
// 查找两个景点在顶点数组中的位置
int v1 = -1, v2 = -1;
for (int j = 0; j < G->vexnum; j++) {
if (strcmp(G->vexs[j].name, v1_name) == 0) {
v1 = j;
}
if (strcmp(G->vexs[j].name, v2_name) == 0) {
v2 = j;
}
}
// 将v2插入到v1的邻接表中
ArcNode *arc1 = (ArcNode*)malloc(sizeof(ArcNode));
arc1->adjvex = v2;
arc1->weight = weight;
arc1->next = G->vexs[v1].firstarc;
G->vexs[v1].firstarc = arc1;
// 将v1插入到v2的邻接表中
ArcNode *arc2 = (ArcNode*)malloc(sizeof(ArcNode));
arc2->adjvex = v1;
arc2->weight = weight;
arc2->next = G->vexs[v2].firstarc;
G->vexs[v2].firstarc = arc2;
}
}
// 打印邻接表图
void printGraph(ALGraph G) {
printf("公园中景点信息如下:\n");
for (int i = 0; i < G.vexnum; i++) {
printf("%d. %s\n", i + 1, G.vexs[i].name);
}
printf("公园中道路信息如下:\n");
for (int i = 0; i < G.vexnum; i++) {
ArcNode *p = G.vexs[i].firstarc;
while (p != NULL) {
printf("%s - %s : %d\n", G.vexs[i].name, G.vexs[p->adjvex].name, p->weight);
p = p->next;
}
}
}
// Dijkstra算法求最短路径
void dijkstra(ALGraph G, int start, int dist[]) {
int visited[MAX_VERTEX_NUM];
for (int i = 0; i < G.vexnum; i++) {
dist[i] = INFINITY;
visited[i] = 0;
}
dist[start] = 0;
visited[start] = 1;
ArcNode *p = G.vexs[start].firstarc;
while (p != NULL) {
dist[p->adjvex] = p->weight;
p = p->next;
}
for (int i = 1; i < G.vexnum; i++) {
int minDist = INFINITY, u = start;
for (int j = 0; j < G.vexnum; j++) {
if (!visited[j] && dist[j] < minDist) {
minDist = dist[j];
u = j;
}
}
visited[u] = 1;
p = G.vexs[u].firstarc;
while (p != NULL) {
if (!visited[p->adjvex] && dist[u] + p->weight < dist[p->adjvex]) {
dist[p->adjvex] = dist[u] + p->weight;
}
p = p->next;
}
}
}
// 打印最短路径
void printPath(ALGraph G, int start, int end, int path[]) {
int stack[MAX_VERTEX_NUM], top = -1;
int p = end;
stack[++top] = p;
while (p != start) {
p = path[p];
stack[++top] = p;
}
printf("%s", G.vexs[stack[top--]].name);
while (top >= 0) {
printf(" -> %s", G.vexs[stack[top--]].name);
}
printf("\n");
}
// 查询任意两个景点之间最短的简单路径
void shortestPath(ALGraph G) {
char v1_name[MAX_NAME_LEN], v2_name[MAX_NAME_LEN];
printf("请输入要查询的两个景点的名称:");
scanf("%s %s", v1_name, v2_name);
int v1 = -1, v2 = -1;
for (int i = 0; i < G.vexnum; i++) {
if (strcmp(G.vexs[i].name, v1_name) == 0) {
v1 = i;
}
if (strcmp(G.vexs[i].name, v2_name) == 0) {
v2 = i;
}
}
if (v1 == -1 || v2 == -1) {
printf("输入的景点名称有误!\n");
return;
}
int dist[MAX_VERTEX_NUM], path[MAX_VERTEX_NUM];
dijkstra(G, v1, dist);
if (dist[v2] == INFINITY) {
printf("%s和%s之间不存在路径!\n", v1_name, v2_name);
} else {
printf("%s到%s的最短路径为:", v1_name, v2_name);
printPath(G, v1, v2, path);
printf("路径长度为:%d\n", dist[v2]);
}
}
int main() {
ALGraph G;
createGraph(&G);
printGraph(G);
shortestPath(G);
return 0;
}
```
说明:
1. 本代码使用邻接表存储图,每个顶点用VNode结构体表示,其中包含了顶点的名称和指向第一个邻接点的指针。每个边用ArcNode结构体表示,其中包含了该边指向的顶点位置、边权值和指向下一个邻接点的指针。邻接表用ALGraph结构体表示,其中包含了顶点数组和顶点数、边数。
2. createGraph函数用于创建邻接表图,首先从终端输入景点数量和每个景点的名称,然后输入道路数量和每条道路连接的两个景点的名称及其长度,最后根据输入构建邻接表。
3. printGraph函数用于打印邻接表图,首先打印每个景点的名称,然后打印每条道路连接的两个景点的名称和长度。
4. dijkstra函数用于求最短路径,采用Dijkstra算法,其中start为起点,dist数组存储起点到每个顶点的最短距离。
5. printPath函数用于打印最短路径,其中end为终点,path数组存储最短路径。
6. shortestPath函数用于查询任意两个景点之间最短的简单路径,首先输入要查询的两个景点的名称,然后调用dijkstra函数求最短路径并打印结果。
7. main函数为程序入口,首先调用createGraph函数创建邻接表图,然后调用printGraph函数打印图,最后调用shortestPath函数查询最短路径。