带你用广度优先搜索实现地铁计费功能

1、地铁是如何实现收费的?

我们平时坐地铁去上班的时候,是否有想过,地铁是怎么计费的呢?因为地铁的线路都比较复杂,一般大城市的地铁网都是错综复杂的,比如广州,目前就有15条线路,假设一条线有20个站点,那么整个地铁网络就会有300个站点,因为地铁可以换乘,从一个起点到达一个终点,会有很多路线。我们都知道,地铁的收费是根据距离来决定的(我们这里先假设每两个站的距离都是相等的),也就是站点越多,收费就越多,通常来说,地铁从一个起点到另外一个点,都是按照最短路径来收费的(不可能按照最长吧?),如何找到这个最短路径呢?我们首先来看看以下简图:
在这里插入图片描述

1.1 数组实现方式

首先来看起点站和目的地是同一条地铁线的情况,比如从A到C站,这种计算距离是十分简单的,我们只要把整条一号线的站点组合成一个数组,就可以计算从其中某个站点到另一个站点的路程。如上图的从A到C,假设A站的id是1,C站的id是3,我们把数组的元素设置为id值,那么总费用S=每站收费*(3-1),如果一站的收费是2元,那么从A到C就是4元。这个过程十分简单!时间复杂度是O(1),十分高效。

1.2 无向图实现方式

起点和目的点在同一条地铁线的情况计算是十分简单的,只需要构造一个数组就能实现。但如果起点和目的地不是同一条线,那么就比较复杂了。比如从一号线的A站作为起点,去二号线的F站,可选择的走法比较多,途中就有以下两种走法:

路线一:A--->B--->C--->D--->E--->F

路线二:A--->B--->F

然而在现实中,两个站点的路线可能不止两条路线了,按照地铁的计费原则,理应是选择最短路径来进行计费的,也就是上面说的路线二。那么系统是怎么找到路线二,并确定它就是最短路径呢?其实,熟悉图论的童鞋早就会想到其实地铁线路,就是个无向图。而无向图中有个经典的算法是广度优先搜索,它可以找到无向图中两点之间的最短路径。

2、广度优先搜索找到两个站点最短路径

为了方便简单实现,我们这里用站点的ID作为图的各个顶点,0代表A,1代表B,2代表C,3代表D,4代表E,5代表F,这样上面的地铁线路图就简化成下面的无向图。于是,求A—>F的最短距离问题就变成求顶点0到顶点5的最短路径。

在这里插入图片描述

2.1 构建站点对象

我们先构造站点对象Station,这里我们主要用到的是站点的stationId,如下代码:

	/**
	 * 站点
	 */
	class Station{
   
		int stationId;//站点id
		String stationName;//站名
		
		public Station(int stationId,String stationName) {
   
			this.stationId = stationId;
			this.stationName = stationName;
		}

	}

2.2 用邻接表构造地铁无向图

我们使用邻接表来表示这个无向图,以下是构造出的站点邻接表。左边的数组代表所有的站点,右边的一个个链表元素代表数组中的站点邻接的站点,比如数组中id为2的站点,有两个邻接站点,分别是id为2和4。
在这里插入图片描述

我们用链表数组stationTable表示这张邻接表,由传入的站点列表stationList作为stationTable的数据源。光是站点还不够,站点是通过一组线路来连接起来的,这个可以通过传入两个站点调用addEdge方法,构造站点与站点的连线。

public class SubwayGraph {
   
	
	int stationCount;//站点总数量
	
	LinkedList<Integer>[] stationTable;//站点邻接表
	
	public SubwayGraph(List<Station> stationList) {
   
		int size = stationList.size();
		this.stationCount = size;
		this.stationTable = new LinkedList[size];
		
		for(Station s : stationList) {
   
			stationTable
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值