实验内容与要求: 用C语言设计江西服装学院的校园平面图,所含景点不少于8个。以图中顶点表示学校内各景点,存放景点的名称、景点介绍信息等;以边表示路径,存放路径长度信息。要求将这些信息保存在文件graph.txt中,系统执行时所处理的数据要对此文件分别进行读写操作。 1.从文件graph.txt中读取相应数据, 创建一个图,使用邻接矩阵表示图; 2.景点信息查询:为来访客人提供校园任意景点相关信息的介绍; 3.问路查询:为来访客人提供校园任意两个景点之间的一条最短路径。
时间: 2024-01-22 12:20:17 浏览: 135
好的,这是一个图论相关的实验任务。我们可以按照以下步骤来实现:
1. 创建邻接矩阵
首先,我们需要从文件中读取景点和路径信息,并存储在邻接矩阵中。邻接矩阵是一个二维数组,其中每个元素表示两个顶点之间是否有路径。如果有路径,该元素的值表示路径长度。如果没有路径,则该元素的值为无穷大。
我们可以使用以下代码来创建一个邻接矩阵:
```c
#define MAX_VERTICES 100 // 最大顶点数
#define INF INT_MAX // 无穷大
int adj_matrix[MAX_VERTICES][MAX_VERTICES]; // 邻接矩阵
int num_vertices = 0; // 顶点数
// 从文件中读取数据并创建邻接矩阵
void create_adj_matrix() {
// 读取文件
FILE *fp = fopen("graph.txt", "r");
if (fp == NULL) {
printf("文件打开失败!\n");
exit(1);
}
fscanf(fp, "%d", &num_vertices);
for (int i = 0; i < num_vertices; i++) {
for (int j = 0; j < num_vertices; j++) {
adj_matrix[i][j] = INF;
}
}
for (int i = 0; i < num_vertices; i++) {
char name[50], desc[100];
int num_edges;
fscanf(fp, "%s%s%d", name, desc, &num_edges);
for (int j = 0; j < num_edges; j++) {
int dest, weight;
fscanf(fp, "%d%d", &dest, &weight);
adj_matrix[i][dest] = weight;
}
}
fclose(fp);
}
```
在这段代码中,我们首先定义了一个 `MAX_VERTICES` 常量,表示最大顶点数。然后定义了一个 `INF` 常量,表示无穷大。接下来定义了一个二维数组 `adj_matrix`,表示邻接矩阵,以及一个变量 `num_vertices`,表示顶点数。
在 `create_adj_matrix()` 函数中,我们首先打开文件,读取顶点数,并初始化邻接矩阵。然后按行读取每个景点的名称、介绍和边数,并读取每个边的目标顶点和边权值,更新邻接矩阵。最后关闭文件。
2. 景点信息查询
现在我们已经创建了邻接矩阵,可以根据用户输入的景点名称来查询景点信息。我们可以使用以下代码来实现:
```c
// 根据名称查找顶点编号
int find_vertex(char *name) {
for (int i = 0; i < num_vertices; i++) {
char vertex_name[50];
sscanf(graph[i], "%s", vertex_name);
if (strcmp(vertex_name, name) == 0) {
return i;
}
}
return -1;
}
// 显示景点信息
void show_vertex_info(int vertex) {
char name[50], desc[100];
sscanf(graph[vertex], "%s%s", name, desc);
printf("名称:%s\n", name);
printf("介绍:%s\n", desc);
}
// 景点信息查询
void vertex_info_query() {
printf("请输入景点名称:");
char name[50];
scanf("%s", name);
int vertex = find_vertex(name);
if (vertex == -1) {
printf("未找到该景点!\n");
} else {
show_vertex_info(vertex);
}
}
```
在这段代码中,我们首先定义了一个 `find_vertex()` 函数,用于根据名称查找顶点编号。它遍历邻接矩阵中的每个顶点,将当前顶点名称与目标名称比较,如果相同则返回该顶点编号,否则返回 -1。
然后定义了一个 `show_vertex_info()` 函数,用于显示景点信息。它从顶点的字符串中解析出名称和介绍,并输出到控制台。
最后定义了一个 `vertex_info_query()` 函数,用于实现景点信息查询。它提示用户输入景点名称,调用 `find_vertex()` 函数查找顶点编号,如果找到则调用 `show_vertex_info()` 函数显示景点信息,否则输出错误信息。
3. 问路查询
最后一个任务是实现问路查询。用户输入起点和终点名称,程序会使用 Dijkstra 算法计算最短路径,并输出路径长度和路径经过的景点名称。以下是实现代码:
```c
// 计算起点到每个顶点的最短路径
void dijkstra(int start, int *dist, int *prev) {
bool visited[MAX_VERTICES] = {false};
for (int i = 0; i < num_vertices; i++) {
dist[i] = INF;
prev[i] = -1;
}
dist[start] = 0;
for (int i = 0; i < num_vertices; i++) {
int min_dist = INF, u;
for (int j = 0; j < num_vertices; j++) {
if (!visited[j] && dist[j] < min_dist) {
min_dist = dist[j];
u = j;
}
}
visited[u] = true;
for (int v = 0; v < num_vertices; v++) {
if (!visited[v] && adj_matrix[u][v] != INF && dist[u] + adj_matrix[u][v] < dist[v]) {
dist[v] = dist[u] + adj_matrix[u][v];
prev[v] = u;
}
}
}
}
// 输出从起点到终点的路径
void print_path(int start, int end, int *prev) {
if (end == start) {
printf("%s", graph[start]);
} else {
print_path(start, prev[end], prev);
printf(" -> %s", graph[end]);
}
}
// 问路查询
void path_query() {
printf("请输入起点名称:");
char start_name[50], end_name[50];
scanf("%s", start_name);
printf("请输入终点名称:");
scanf("%s", end_name);
int start = find_vertex(start_name);
int end = find_vertex(end_name);
if (start == -1 || end == -1) {
printf("未找到起点或终点!\n");
return;
}
int dist[MAX_VERTICES];
int prev[MAX_VERTICES];
dijkstra(start, dist, prev);
if (dist[end] == INF) {
printf("无法到达终点!\n");
} else {
printf("最短路径长度:%d\n", dist[end]);
printf("路径:");
print_path(start, end, prev);
printf("\n");
}
}
```
在这段代码中,我们首先定义了一个 `dijkstra()` 函数,用于计算起点到每个顶点的最短路径。它使用 Dijkstra 算法,使用一个数组 `dist` 存储起点到每个顶点的最短路径长度,使用一个数组 `prev` 存储当前顶点在最短路径上的前一个顶点。
然后定义了一个 `print_path()` 函数,用于输出从起点到终点的路径。它使用递归方式输出路径。
最后定义了一个 `path_query()` 函数,用于实现问路查询。它提示用户输入起点和终点名称,调用 `find_vertex()` 函数查找顶点编号,然后调用 `dijkstra()` 函数计算最短路径。如果终点不可达,则输出错误信息,否则输出最短路径长度和路径经过的景点名称。
完整代码如下:
阅读全文