|
|
@ -66,3 +66,57 @@
|
|
|
|
用户输入:无
|
|
|
|
用户输入:无
|
|
|
|
系统输出:地铁线路和站点在地图上的显示,方便用户更直观地了解线路位置和路线。
|
|
|
|
系统输出:地铁线路和站点在地图上的显示,方便用户更直观地了解线路位置和路线。
|
|
|
|
2. 系统设计
|
|
|
|
2. 系统设计
|
|
|
|
|
|
|
|
2.1 概要设计
|
|
|
|
|
|
|
|
系统划分为以下模块:
|
|
|
|
|
|
|
|
1.用户输入模块:用户通过输入起始站点和终点站点,触发系统查询和计算。
|
|
|
|
|
|
|
|
2.数据存储模块:系统将地铁线路和站点信息存储在一个数据结构中,并提供查询和修改功能。
|
|
|
|
|
|
|
|
3.路径计算模块:该模块通过获取用户输入的起始站点和终点站点,并利用存储在数据结 构中的地铁线路和站点信息,计算出最优路径。
|
|
|
|
|
|
|
|
4.输出模块:该模块将最优路径输出给用户,以便用户按照路径指引乘坐地铁。
|
|
|
|
|
|
|
|
2.2 数据结构设计
|
|
|
|
|
|
|
|
通过比较邻接矩阵、邻接表、查找表和不相交集等数据结构,我们选择使用邻接表作为数据结构。邻接表具有占用空间小、查询速度快等优势,适合储存大量的地铁线路和站点信息。
|
|
|
|
|
|
|
|
邻接表
|
|
|
|
|
|
|
|
邻接表是一种表示图形的数据结构,它用于描述地铁网络中的站点之间的连接关系。在邻接表中,每个站点对应一个链表,链表中的每个节点表示与该站点相邻的另一个站点。具体而言,我们可以用如下的结构体表示邻接表中的每个节点:
|
|
|
|
|
|
|
|
struct AdjListNode {
|
|
|
|
|
|
|
|
int destination; // 相邻站点编号
|
|
|
|
|
|
|
|
int weight; // 连接权重(例如两站之间的距离、换乘次数等)
|
|
|
|
|
|
|
|
struct AdjListNode* next; // 下一个相邻节点的指针
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
每个链表的头节点可以由一个数组来维护,例如:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct Station {
|
|
|
|
|
|
|
|
char name[20]; // 站点名称
|
|
|
|
|
|
|
|
int id; // 站点编号
|
|
|
|
|
|
|
|
struct AdjListNode* head; // 相邻节点链表的头节点指针
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Station stations[MAX_STATION_NUM]; // 站点数组
|
|
|
|
|
|
|
|
在这个结构中,我们为每个站点记录了它的名称、编号和相邻节点链表的头节点指针。这样的话,我们就可以通过遍历这些链表来获取某一站点的所有邻居站点。同时,由于链表中的每个节点包含了相邻站点的编号和连接权重,因此我们也可以在搜索路径时方便地计算出经过某一条路径的总长度或换乘次数。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
示意图如下,表示了一个包含 4 个站点和 5 条连接边的地铁网络的邻接表结构:
|
|
|
|
|
|
|
|
stations[]:
|
|
|
|
|
|
|
|
index 0 1 2 3
|
|
|
|
|
|
|
|
+---------+---------+---------+---------+
|
|
|
|
|
|
|
|
| name | id | head | |
|
|
|
|
|
|
|
|
+---------+---------+---------+---------+
|
|
|
|
|
|
|
|
| "PARK" | 0 | +---|-----+ |
|
|
|
|
|
|
|
|
+---------+---------+---------+---------+
|
|
|
|
|
|
|
|
| "GATE" | 1 | +---|-----+ |
|
|
|
|
|
|
|
|
+---------+---------+---------+---------+
|
|
|
|
|
|
|
|
| "TOWER" | 2 | +---|-----|--+|
|
|
|
|
|
|
|
|
+---------+---------+---------+----|----+
|
|
|
|
|
|
|
|
| "HALL" | 3 | +---|-----+ |
|
|
|
|
|
|
|
|
+---------+---------+---------+---------+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
adj_list[]:
|
|
|
|
|
|
|
|
station 0: PARK
|
|
|
|
|
|
|
|
head -> O |weight=5| -> 1 |weight=3| -> 2 |weight=1| -> null
|
|
|
|
|
|
|
|
station 1: GATE
|
|
|
|
|
|
|
|
head -> O |weight=3| -> 0 |weight=4| -> 3 |weight=2| -> 2 |weight=1| -> null
|
|
|
|
|
|
|
|
station 2: TOWER
|
|
|
|
|
|
|
|
head -> O |weight=1| -> 1 |weight=1| -> 3 |weight=3| -> null
|
|
|
|
|
|
|
|
station 3: HALL
|
|
|
|
|
|
|
|
head -> O |weight=2| -> 1 |weight=5| -> null
|
|
|
|
|
|
|
|
在这个示意图中,stations 数组中的每个元素都包含了它所代表的站点的名称、编号和相邻节点链表的头节点指针。例如,stations[0] 表示 "PARK" 站,它的编号为 0,与相邻的站点是 "GATE"、"TOWER" 和 "HALL"。其中,与 "GATE" 站相连的边的权重为 5,与 "TOWER" 相连的边的权重为 3,与 "HALL" 相连的边的权重为 1。而对应的 adj_list 数组则记录了每个站点相邻节点链表的具体内容,其中每个节点包含了相邻站点的编号和连接权重。
|
|
|
|
|
|
|
|
2.3 算法设计
|
|
|
|
|
|
|
|
我们选择Dijkstra算法作为路径计算模块的核心算法。Dijkstra算法是一种广泛应用于最短路径问题上的算法,具有速度快、结果正确性高、易于实现等优势。它通过不断更新起点到每个点的最短距离,并使用优先队列维护每个点的最短距离,直到计算出终点的最短路径。
|
|
|
|
|
|
|
|
Dijkstra算法
|
|
|
|
|
|
|
|
用户输入起点站和终点站,程序使用图论算法在地铁线路图中寻找到两个站之间的一条最短路径。此时使用Dijkstra算法找出最短路径。
|
|
|
|