算法:
已知起点站A,终点站B。假设最大换乘次数3,初始值为0。
1、根据起点站获得经过该站点的车次。
2、按序分析每路车次。
3、取得某个车次获得该站点的后续站点。
4、如果发现后续站点是B,就找到一条路径。记录该路径。并退出在本线路上的搜索。如果后续站点不是B,就继续分析后续站点的后续站点。直到该线路的终点站。
5、如果该线路的后续站点不存在B,则获得该线路的经过本站点的后续站点,重复过程1~4,换乘次数加1,如果换乘次数为4则退出该线路的搜索。
6、取得第二个车次,分析同上。
7、分析完所有路线,如果不存在,就提醒用户增加换乘次数,或者打的。如果存在按换乘次数从小到大排列换乘路线。
-------------------------------------
线路表:
code 线路编号
name 线路名称
buscode 车次
地点表:
stationcode 站编号
station 站名
中间表:
code 线路编号
stationcode 站编号
seqnumber 某站在线路中的顺序
=======================================
线路表:
每条线路对应一路车次。按序存放各站点。每条线路有两个方向。
站点表:
每个站点,有经过该站点的所有车次。
这是邹健写的公交线路查询存储过程
SQL代码
--示例数据
create table Line(lineID int,state nvarchar(10),orderid int,primary key(lineID,orderid))
insert Line select 1,'鼓楼' ,1
union all select 1,'新街口',2
union all select 1,'汽车站',3
union all select 1,'火车站',4
union all select 2,'新街口',1
union all select 2,'飞机场',2
union all select 2,'天安门',3
union all select 3,'天安门',1
union all select 3,'石门坎',2
union all select 3,'驾校' ,3
go
--查询的存储过程
create proc p_qry
@begin_state nvarchar(10),
@end_state nvarchar(10)
as
set nocount on
declare @l int
set @l=0
select lineID,line=cast('('+rtrim(lineID)+': '+rtrim(state) as varchar(8000))
,state,orderid=orderid+1,level=@l,gid=1
into #t from Line where state=@begin_state
while @@rowcount>0 and not exists(select * from #t where state=@end_state)
begin
set @l=@l+1
insert #t(line,lineID,state,orderid,level,gid)
select
line=a.line+case
when a.lineID=b.lineID
then '->'+rtrim(b.state)
else ') => ('+rtrim(b.lineID)+': '+rtrim(b.state)
end,
lineID=b.lineID,state=b.state,orderid=b.orderid+1,@l,
case when a.lineID=b.lineID then a.gid else a.gid+1 end
from #t a,Line b
where a.level=@l-1
and(
a.lineID=b.lineID and a.orderid=b.orderid
or
a.state=b.state and a.lineID<>b.lineID)
end
select 起点站=@begin_state
,终点站=@end_state
,转车次数=gid
,经过站数=case when gid<3 then @l else @l-gid+2 end
,乘车线路=line+')'
from #t where level=@l and state=@end_state
go
--调用
exec p_qry '鼓楼','火车站'
exec p_qry '鼓楼','飞机场'
exec p_qry '鼓楼','石门坎'
go
--删除测试
drop table Line
drop proc p_qry
结合这个存储过程
SQL代码
CREATE TABLE T_Line(
ID nvarchar(10), --公交线路号
Station nvarchar(10), --站点名称
Orders int) --行车方向(通过它反应每个站的上一个、下一个站)
INSERT T_Line
SELECT N'8路' ,N'站A',1 UNION ALL
SELECT N'8路' ,N'站B',2 UNION ALL
SELECT N'8路' ,N'站C',3 UNION ALL
SELECT N'8路' ,N'站D',4 UNION ALL
SELECT N'8路' ,N'站J',5 UNION ALL
SELECT N'8路' ,N'站L',6 UNION ALL
SELECT N'8路' ,N'站M',7 UNION ALL
SELECT N'20路' ,N'站G',1 UNION ALL
SELECT N'20路' ,N'站H',2 UNION ALL
SELECT N'20路' ,N'站I',3 UNION ALL
SELECT N'20路' ,N'站J',4 UNION ALL
SELECT N'20路' ,N'站L',5 UNION ALL
SELECT N'20路' ,N'站M',6 UNION ALL
SELECT N'255路',N'站N',1 UNION ALL
SELECT N'255路',N'站O',2 UNION ALL
SELECT N'255路',N'站P',3 UNION ALL
SELECT N'255路',N'站Q',4 UNION ALL
SELECT N'255路',N'站J',5 UNION ALL
SELECT N'255路',N'站D',6 UNION ALL
SELECT N'255路',N'站E',7 UNION ALL
SELECT N'255路',N'站F',8
GO
--引用邹建的.乘车线路查询存储过程
CREATE PROC p_qry
@Station_Start nvarchar(10),
@Station_Stop nvarchar(10)
AS
SET NOCOUNT ON
DECLARE @l int
SET @l=0
SELECT ID,Station,
Line=CAST('('+RTRIM(ID)+': '+RTRIM(Station) as nvarchar(4000)),
Orders=Orders,
[Level]=@l
INTO # FROM T_Line
WHERE Station=@Station_Start
WHILE @@ROWCOUNT>0
AND NOT EXISTS(SELECT * FROM # WHERE Station=@Station_Stop)
BEGIN
SET @l=@l+1
INSERT #(Line,ID,Station,Orders,[Level])
SELECT
Line=a.Line+CASE
WHEN a.ID=b.ID THEN N'->'+RTRIM(b.Station)
ELSE N') ∝ ('+RTRIM(b.ID)
+N': '+RTRIM(b.Station) END,
b.ID,b.Station,b.Orders,@l
FROM # a,T_Line b
WHERE a.[Level]=@l-1
AND(a.Station=b.Station AND a.ID<>b.ID
OR a.ID=b.ID AND(
a.Orders=b.Orders+1
OR
a.Orders=b.Orders-1))
AND LEN(a.Line)<4000
AND PATINDEX('%[ >]'+b.Station+'[-)]%',a.Line)=0
END
SELECT N'起点站'=@Station_Start
,N'终点站'=@Station_Stop
,N'乘车线路'=Line+N')'
FROM #
WHERE [Level]=@l
AND Station=@Station_Stop
IF @@ROWCOUNT =0 --如果未有可以到达的线路,则显示处理结果表备查
SELECT * FROM #
GO
--调用
EXEC p_qry N'站A',N'站L'
/*--结果
起点站 终点站 乘车线路
---------- ------------ -----------------------------------------------------------
站A 站L (8路: 站A->站B->站C->站D->站J->站L)
--*/