列车时刻表采用什么样的数据结构较好

ancient 2002-09-11 11:04:05
要求实现按车次查询,车站时刻表和起点终点查询三种查询方法
我的想法是为每个车次建立一个链表,链表每个节点代表一个城市
在起点终点查询中如果考虑用户转车要找出最短路径可能吗(我是说要花费多大的代价,我想不到好的方法)
...全文
155 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Lawrence444 2002-09-12
  • 打赏
  • 举报
回复
就是。其实我写过类似列车时刻表的东西,而且是不用数据库的。

第一个问题是数据量很大。你们可能难以想象,一个完整列车时刻表用的数据,不加任何索引就有10M。数据条目也极多(我记得开始用数据库的时候大概就是有100000条以上)。如果再加上各种价格的运算,就更为复杂了。不要以为价格运算很简单,中国铁路实际上有一套乱复杂的价格系统。我写过一个运算程序,大概2000行,中间查表无数。

如果不用数据库,建立一个索引结构是很重要的(要不然怎么查100000条记录啊),可以用B树或者类似的结构。算法上倒不是太难。用一点Dijkstra就搞定了(可以调整图中边的权用时间、价格还是什么)。总体说来是比较烦拉,还不如去买一个呢。
fzel_net 2002-09-12
  • 打赏
  • 举报
回复
孩皮妞野 2002-09-12
  • 打赏
  • 举报
回复
这是一种时间和空间的tradeoff, 如果你想省空间,不可避免要付出时间的代价。


还有关于转车,可能有几个经验标准:
1。有直达车的不要转车;
2。要转车的要尽可能缩短旅行时间,这里要考虑转车需要耗费的时间。
3。还要考虑尽可能减少转车次数,2和3一般是不矛盾的,但也不排除特殊情况,在特殊情况下,是先考虑转车次数还是旅行时间。这里面恐怕不那么简单,要有个评价方案好坏的函数。


我的建议,先在pc上做出算法,在想办法压缩需要使用的空间。也就是想找一个可行解, 再往自己想要的方向修剪。压缩的方法其实与数据库的道理相通。比如有256个[或以下]城市,那么每个城市可以用一个字节来代表,而维护一个城市到其代码的表,这就相当于一个数据库表:
city_id city_name
0 北京
1 上海
...

车次一般小于10000,可以用10位来存储,那么还有6位,或者再加一个字节14位可以放其他某个信息。等等。

关键是算法,dijkstra或其他算法同样是适用的。还有容器,使用什么来容纳你的基础信息,不要说时间不要紧,按进去算半天,谁用你的东西?
ancient 2002-09-12
  • 打赏
  • 举报
回复
首先,要做的都西不在pc上运行,没有数据库支持
第二,需要尽可能的节约每一个byte的存储空间(比查询的时间更重要)
第三,基于第二点原因,在有转车的查询中,不可能用常规的方法给出图的完整信息,只能以列车为单位来索引经过的城市
孩皮妞野 2002-09-12
  • 打赏
  • 举报
回复
DaNiao, 他可能是palmtop之类的设备,主辅存都紧张。
DaNiao 2002-09-12
  • 打赏
  • 举报
回复
不在PC上运行?
那更应该使用数据库管理系统了
比如ORACLE DB2都是可以在从PC到巨型机的各种系统上运行的,而且兼容性非常好
我实在想不出有什么常见的机器上没有ORACLE客户端的
DaNiao 2002-09-12
  • 打赏
  • 举报
回复
我记得有人(一个大师级人,可惜我忘了是谁了)曾经说过
大部分程序员都对自己的编程水平过分自信,而不去使用现有的库和数据库管理系统,
但他们写出的程序实际上很少会比现有的系统好,这是导致很多项目失败的原因
孩皮妞野 2002-09-11
  • 打赏
  • 举报
回复
>>在起点终点查询中如果考虑用户转车要找出最短路径可能吗(我是说要花费多大的代价,我想不到好的方法)


这个也是可以的,可能的方法之一就是单源最短路径,查一下dijkstra's algorithm.

你的这个表本质上就是一个网络,当然你要补充很多数据,比如有一班:
396 次 A -> E
沿途停靠依次为 B; C; D

你要保存:

stop next_stop seq_no distance(KM)
A B 396 50
B C 396 20
C D 396 60
D E 396 30

作为前面的表的补充,这样你就有了一个完整的铁路网络,使用dijkstra算法好像可以在O(nlogn)时间完成你的任务。

孩皮妞野 2002-09-11
  • 打赏
  • 举报
回复
关键看你想实现哪些操作。

如果没有插入/删除,我觉得可以用一个结构放这些信息,把每个车次的信息放在一个vector里。根据需要查询的方式,维护几个排序好的指针数组:

struct time_table_entry{
int seq_no; // 或者用字符型
string start, end; // 起点终点
// 其它数据域
};

vector<time_table_entry> time_table;

//把所有的车次信息放入上表

vector<time_table_entry *> seq_order; // 按车次排序的指针数组

vector<time_table_entry *> start_order, // 按始发站排序的指针数组

vector<time_table_entry *> end_order, // 按终到站排序的指针数组

在初始化seq_order, start_order,end_order后查询可以以O(logn)的效率完成。就是用简单的2分搜索。


孩皮妞野 2002-09-11
  • 打赏
  • 举报
回复
对呀,对于查询一类的直接用数据库的SQL, 灵活性之强,编程工作量之小,无与伦比。 不知道贴主为什么舍近求远。

当然你要的查转车之类的能力可能确实需要编程,一个好的算法非常关键。
Lawrence444 2002-09-11
  • 打赏
  • 举报
回复
呵呵,列车时刻表还有一条,就是停车和开车的时间。

ALNG说的没错,这样是可以的。不过实际应用的时候多会使用数据库。因为车次之类的录入会很麻烦。

干吗这么多人想做列车时刻表啊?干脆编个软件拿来卖算了。

33,007

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧