项目介绍:
1. 地铁站点路线显示
从本地文件中读取地铁线路站点数据,并在 Qt 界面中显示地铁路线及站点。当鼠
标悬浮在地铁站点上时,显示站点详细信息;实现界面的缩小放大。
2. 添加新地铁线路及站点
新地铁线路开通时,可以手动添加新开通的地铁线路到系统中;可以手动添加站
点到新旧地铁路线中。
3. 地铁最少换乘次数路线查询
查询出从起点站到终点站换乘次数最少的乘车路线。
4. 地铁最少时间换乘路线查询
查询出从起点站到终点站用时最少的乘车路线。
5. 帮助文档
帮助文档可以帮忙使用者快速的了解软件的使用方法。
一、主界面布局
二、地铁信息存储
1、学习数据结构中图的存储。
图的存储方法有好几种,如邻接矩阵法,邻接表法,十字链表法,邻接多重表。当一个图为稀疏图时,使用邻接矩阵会浪费大量存储空间。邻接表法结合了顺序存储和链式存储方法,减少了不必要的浪费。
邻接表(Adjacency List) 是图的一种链式存储结构,在邻接表中,对图中每个顶点建立一个单链表,第i个单链表中的节点表示依附于顶点Vi的边(对有向图是以顶点Vi为尾的弧)。每个节点由3个域组成,其中邻接点域(adjvex)指示与顶点vi邻接的点在图中的位置,链域(nextarc)指示下一条边或弧的节点;数据域(info)存储和边或弧相关的信息,如权值等。每个链表上附设一个表头节点。在表头节点中,除了设有链域(firstarc)指向链表中的第一个节点之外,还设有存储顶点Vi的名或者其他有关信息的数据域(data)。
在构建图时,需要两个结构体,一个存储图中节点的信息,便是上面介绍的头节点,一个是两个节点之间边的信息,便是上面的表(边)节点。 采用一个一维数组存储头结点信息,然后为每个头结点建立一个链表,让头结点作为这个链表的表头节点(具体实现方法便是让头结点内的指针firstarc 指向链表的首地址),链表中存储的正是和这个头结点相关联的表节点(边的信息),这些边都是尾部和头结点相连。表节点中的adjvex存储的是与这条边关联的另一个头结点在数组中的索引(边的箭头所关联的头节点),表节点中的nextarc则是存储的该链表表头相关联的另一条边的信息。
2、选择合适的容器
地铁站点、路线完全符合图的数据结构,所以地铁站点、路线的存储可以参考图的邻接表的存储结构,参考下图:
容器存储:
所以该项目采用的容器为:
//存储所有站点信息,用stations的索引作为站点的唯一索引
QVector<Station>stations;
//<站点名,站点在stations中的索引>
QHash<QString, int> stationsHash;
//graph[i]代表stations[i]站点的头结点
// graph[i]容器内存储的是与stations[i]站点相连的站点的唯一索引
QVector<QVector<Node>>graph;
三、读取地铁线路信息
导入数据库信息后,将各个站点信息遍历,存储到line中,再利用函数生成图结构。
//生成图结构
void SubwayGraph::makeGraph()
{
graph.clear();
graph=QVector<QVector<Node>>(stations.size(), QVector<Node>());
for (auto &a : edges)
{
double dist=stations[a.first].distance(stations[a.second]);
graph[a.first].push_back(Node(a.second, dist));
graph[a.second].push_back(Node(a.first, dist));
}
}