- 任务描述
- 根据用户从键盘输入的城市名(用汉语拼音表示)以及城市间的道路连接距离(用整数公里表示),创建一个简单的城市交通网络图。(菜单项:创建地图)(为了测试方便,城市结点考虑10个以内)
- 输出用户咨询的两个城市间的最短路径和距离。(菜单项:查询路线)
- 按用户指定的出发城市用深度优先搜索显示所有搜索线路上的城市清单。(菜单项:显示搜索路线)
- 若有30个城市,分别给它们编号1---30。先从键盘由用户输入若干个城市编号,请建一个二叉排序树(用二叉链表表示)存储,然后按层次遍历输出该二叉树的结果(要求每输出完一层就换行,每个输出项为“城市编号+L或R”,其中L代表左孩子,R代表右孩子),然后由用户输入若干个需要删除的城市编号,再按层次遍历输出该二叉树的结果(建立和删除的城市编号的数量由用户决定)。(菜单项:城市名排序)
5. 若有30个城市,分别给它们编号1---30。先从键盘由用户输入若干个城市编号,请建一个二叉平衡树(用二叉链表表示)存储,然后按层次遍历输出该二叉树的结果(要求每输出完一层就换行,每个输出项为“城市编号+L或R”,其中L代表左孩子,R代表右孩子)(建立和删除的城市编号的数量由用户决定)。(菜单项:城市名排序)
测试数据
好的,我们可以为功能二(查询最短路径)和功能三(显示从某个城市出发的所有可达城市)生成测试数据。以下是包含六个城市的有向图及其测试数据。
六个城市示例
城市列表:
北京
上海
广州
深圳
杭州
南京
道路连接及距离(有向):
北京 -> 上海 (1200 km)
北京 -> 南京 (900 km)
上海 -> 杭州 (180 km)
上海 -> 广州 (1500 km)
广州 -> 深圳 (150 km)
杭州 -> 南京 (300 km)
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_NAME_LENGTH 20 #define MAX_VERTICES 10 typedef struct Vertex { char name[MAX_NAME_LENGTH]; struct Edge *adjList; } Vertex; typedef struct Edge { int destination; int weight; struct Edge *next; } Edge; typedef struct Graph { int numVertices; Vertex *vertices; } Graph; // 创建一个图 Graph *createGraph(int numVertices) { Graph *graph = (Graph *)malloc(sizeof(Graph)); if (graph == NULL) { printf("内存分配失败。\n"); return NULL; } graph->numVertices = numVertices; graph->vertices = (Vertex *)malloc(numVertices * sizeof(Vertex)); if (graph->vertices == NULL) { printf("内存分配失败。\n"); free(graph); return NULL; } for (int i = 0; i < numVertices; i++) { graph->vertices[i].adjList = NULL; } return graph; } // 向图中添加一条边 void addEdge(Graph *graph, const char *srcName, const char *destName, int weight) { int srcIndex = -1, destIndex = -1; for (int i = 0; i < graph->numVertices; i++) { if (strcmp(graph->vertices[i].name, srcName) == 0) { srcIndex = i; } if (strcmp(graph->vertices[i].name, destName) == 0) { destIndex = i; } } if (srcIndex == -1 || destIndex == -1) { printf("无效的城市名称。\n"); return; } Edge *newEdge = (Edge *)malloc(sizeof(Edge)); if (newEdge == NULL) { printf("内存分配失败。\n"); return; } newEdge->destination = destIndex; newEdge->weight = weight; newEdge->next = graph->vertices[srcIndex].adjList; graph->vertices[srcIndex].adjList = newEdge; } // 打印图 void printGraph(Graph *graph) { for (int i = 0; i < graph->numVertices; i++) { printf("%s -> ", graph->vertices[i].name); Edge *current = graph->vertices[i].adjList; while (current != NULL) { printf("(%s, %d) -> ", graph->vertices[current->destination].name, current->weight); current = current->next; } printf("NULL\n"); } } // 释放图的内存 void freeGraph(Graph *graph) { for (int i = 0; i < graph->numVertices; i++) { Edge *current = graph->vertices[i].adjList; while (current != NULL) { Edge *temp = current; current = current->next; free(temp); } } free(graph->vertices); free(graph); } // 使用 Dijkstra 算法找到最短路径 void shortestPath(Graph *graph, const char *srcName, const char *destName) { int srcIndex = -1, destIndex = -1; for (int i = 0; i < graph->numVertices; i++) { if (strcmp(graph->vertices[i].name, srcName) == 0) { srcIndex = i; } if (strcmp(graph->vertices[i].name, destName) == 0) { destIndex = i; } } if (srcIndex == -1 || destIndex == -1) { printf("无效的城市名称。\n"); return; } int *distance = (int *)malloc(graph->numVertices * sizeof(int)); int *parent = (int *)malloc(graph->numVertices * sizeof(int)); int *visited = (int *)malloc(graph->numVertices * sizeof(int)); if (!distance || !parent || !visited) { printf("内存分配失败。\n"); free(distance); free(parent); free(visited); return; } for (int i = 0; i < graph->numVertices; i++) { distance[i] = -1; parent[i] = -1; visited[i] = 0; } distance[srcIndex] = 0; for (int i = 0; i < graph->numVertices; i++) { if (!visited[i]) { Edge *current = graph->vertices[i].adjList; while (current != NULL) { if (distance[current->destination] == -1 || distance[current->destination] > distance[i] + current->weight) { distance[current->destination] = distance[i] + current->weight; parent[current->destination] = i; } current = current->next; } visited[i] = 1; } } if (distance[destIndex] == -1) { printf("没有找到路径。\n"); } else { int path[graph->numVertices], pathIndex = 0; int currentIndex = destIndex; while (currentIndex != -1) { path[pathIndex++] = currentIndex; currentIndex = parent[currentIndex]; } printf("从 %s 到 %s 的最短路径: ", srcName, destName); for (int i = pathIndex - 1; i >= 0; i--) { printf("%s", graph->vertices[path[i]].name); if (i != 0) { printf(" -> "); } } printf("\n距离: %d km\n", distance[destIndex]); } free(distance); free(parent); free(visited); } // 深度优先搜索显示所有搜索线路上的城市清单 void dfs(Graph *graph, int startVertex, int visited[MAX_VERTICES]) { printf("%s ", graph->vertices[startVertex].name); visited[startVertex] = 1; Edge *current = graph->vertices[startVertex].adjList; while (current != NULL) { if (!visited[current->destination]) { dfs(graph, current->destination, visited); } current = current->next; } } void displaySearchRoute(Graph *graph, const char *startName) { int startIndex = -1; for (int i = 0; i < graph->numVertices; i++) { if (strcmp(graph->vertices[i].name, startName) == 0) { startIndex = i; break; } } if (startIndex == -1) { printf("无效的城市名称。\n"); return; } int visited[MAX_VERTICES] = {0}; printf("从 %s 出发的所有搜索路线: \n", startName); dfs(graph, startIndex, visited); printf("\n"); } int main() { Graph *graph = NULL; int choice; do { printf("\n菜单:\n"); printf("1. 创建地图\n"); printf("2. 查询路线\n"); printf("3. 显示搜索路线\n"); printf("4. 退出\n"); printf("请输入您的选择: "); scanf("%d", &choice); switch (choice) { case 1: int numVertices; printf("请输入城市数量: "); scanf("%d", &numVertices); graph = createGraph(numVertices); if (graph == NULL) { printf("无法创建地图。\n"); continue; } for (int i = 0; i < numVertices; i++) { char cityName[MAX_NAME_LENGTH]; printf("请输入城市名称 %d: ", i + 1); scanf("%s", cityName); strncpy(graph->vertices[i].name, cityName, sizeof(graph->vertices[i].name) - 1); graph->vertices[i].name[sizeof(graph->vertices[i].name) - 1] = '\0'; } int numEdges; printf("请输入边的数量: "); scanf("%d", &numEdges); for (int i = 0; i < numEdges; i++) { char srcName[MAX_NAME_LENGTH], destName[MAX_NAME_LENGTH]; int weight; printf("请输入起始城市、目的城市和距离(km): "); scanf("%s %s %d", srcName, destName, &weight); addEdge(graph, srcName, destName, weight); // 生成有向图 } printGraph(graph); break; case 2: if (graph == NULL) { printf("请先创建地图。\n"); continue; } char srcName[MAX_NAME_LENGTH], destName[MAX_NAME_LENGTH]; printf("请输入起始城市和目的城市名称: "); if (scanf("%s %s", srcName, destName) != 2) { printf("输入错误,请重新输入。\n"); continue; } shortestPath(graph, srcName, destName); break; case 3: if (graph == NULL) { printf("请先创建地图。\n"); continue; } char startName[MAX_NAME_LENGTH]; printf("请输入出发城市名称: "); if (scanf("%s", startName) != 1) { printf("输入错误,请重新输入。\n"); continue; } displaySearchRoute(graph, startName); break; case 4: if (graph != NULL) { freeGraph(graph); } printf("退出程序。\n"); break; default: printf("无效的选择,请重新输入。\n"); break; } } while (choice != 4); return 0; }