数据结构课程设计 火车订票系统.docx
《数据结构课程设计 火车订票系统.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计 火车订票系统.docx(35页珍藏版)》请在冰点文库上搜索。
数据结构课程设计火车订票系统
软件课程设计--C语言设计火车票订票系统之源代码(模拟数据库功能)(需求分析+可行性分析)
设计题目:
火车订票系统
小组成员:
指导教师:
完成时间:
一.需求设计:
1.每条线路所涉及的信息有:
起点、终点、站名、车次、、票价、时间、座位号。
2.作为示意系统,全部数据可以只放在内存中。
3.系统能实现的功能和操作如下:
①.查询路线:
根据旅客提出的终点站名输入下列信息:
车次、车站名。
②.承办订票业务:
根据客户提出的要求查询该车次票额的情况,若尚有余票,则为客户办理订票手续,输出座位号;若已满员或余票额少于订票额,则需重新查询客户要求,若需要可登记排队候补。
③.承办退票业务:
根据客户提供的情况(车次、时间、座位号)为客户办理退票手续,然后查询该车次是否有人排队候补,首先询问排在第一的客户,若所退票额能满足他的要求,则为他办理订票手续,否则依次询问其他排队候补的客户。
④登记旅客情况:
包括旅客姓名,性别,年龄,家庭住址,联系方式等。
⑤统计功能:
将每次车的订票,退票结果统计出来。
⑥管理功能:
列车管理员可以通过调用函数来查看车票极其用户情况.
⑦.查询功能:
用户可以查询自己需要的车辆信息.
二.总体设计
1.程序流程图:
按1键
按2键
按3键
按4键
进入in函数
进入book函数
进入inquire函数
进入cancel函数
按5键
进入you函数
2.总体设计说明:
①.数据结构设计:
程序=数据结构+算法,一个好的程序必定有一个好的数据结构.本设计主要考虑车票信息和用户信息的数据结构.
车票信息采用半十字链表.横向链表中的每一个结点包含以下内容:
车次,起始站,发车时间,指向下一个结点的指针,指向中途站的指针.纵向链表中每一个结点包含以下内容:
从始发站开始的依次到站,票价,到达时间,是否已被购买标识,才用mark标识,当mark为1时车票已售出,当mark为0时车票还未售出.以及指向下一个结点的指针.纵向链表采用循环链表,尾指针指向首指针.
未购票用户信息使用队列来保存,因为考虑到用户会预订票,所以把用户以来订票的时间早晚排在队中.先来先买,后来后买.队列中的每个元素包含以下内容:
用户姓名,身份证号码,想要购票的车次,起始站,要到的站,时间.
已经购票用户信息使用一个单链表来保存,链表中的没个结点包含以下内容:
用户姓名,身份证号码,已购车票的车次,出发时间,到达时间.
车票信息链表示意图:
车次
起始站
发车时间
downn
next
下一站名
到站时间
票价
mark
next
座位号
未购票用户信息队列:
用户姓名
购票的车次
起始站
要到的站
达到时间
用户姓名
购票的车次
起始站
要到的站
达到时间
注:
座位号包含在车次号中
已购票用户信息链表示意图:
用户姓名
身份证号码
已购车票的车次号
出发时间
到达时间
注:
座位号包含在车次号中
②算法的设计:
主函数:
利用case语句实现用户界面,用户输入需要的服务的数字代码,程序就会转到相应的函数,实现相应的功能。
在主函数开始处做下First标识,以便在其他函数中使用goto语句返回主函数的用户界面。
In()函数:
In()函数负责输入各种信息,链表中车票信息的初始值.
Book()函数:
Book()函数负责订票功能.主要是遍历整个链表,查找到需要订票的结点后修改其mark值.
Inquire()函数:
Inquire()函数主要负责查询功能.主要是遍历整个链表查找到需要的结点,然后输出.
Cancel()函数:
Cancel()函数主要负责退票功能.主要是遍历整个链表查找到需要的结点,然后修改mark的值.
You()函数:
You()函数主要负责输入用户信息,主要是创建一个单链表,将用户信息放入.并提供管理人员的查询功能.
Find()函数:
Find()函数主要负责查询用户信息,遍历整个单链表后,输出需要的信息.
Total()函数:
Total()函数主要负责统计整个订票系统的情况.
三.详细设计:
1.主函数:
①程序代码:
Main()
{int*t;
intc;
First:
printf(“welcometoourticketsystem!
\n”);
printf(“1.intputthedata.\n”); /*按1键输入数据*/
printf(“2.booktheticket.\n”); /*按2键订车票*/
printf(“3.inquiretheticket.\n”); /*按3键查询车票*/
printf(“4.canceltheticket.\n”); /*按4键退车票*/
printf(“5.inputyourowndata.\n”); /*按5键输入个人信息*/
scanf(“%d”,&c);
switch(c)
{case‘1’:
t=in();break;
case‘2’:
book();break;
case‘3’:
inquire();break;
case‘4’:
cancel();break;
case ‘5’:
you() ;break;
default :
printf(“youenteranerrornumber\n”);}}
②功能说明:
通过printf语句,输出提示用户选择的信息.用户看到后,按下自己需要功能的代号.然后程序进入实现该功能函数完成用户所需要的功能.
2.In()函数:
①程序流程图:
建立横向链表头结点
输入m,n的值
For循环,m是否为0
否
建立结点
向结点输入数据
For循环,n是否为0
否
建立纵向结点
向结点输入数据
是
返回头指针
Goto到用户界面
②程序代码:
structticket*in() /*一个返回指针形的函数*/
{
structticket*head; /*头结点*/
structticket*p1,*p2;
structstation*s1,*s2;
intm,n;
inti;
p1=p2=(structticket*)malloc(len); /*建立横向链表的头结点*/
scanf("%d",&m); /*输入一共所需的车票信息总数*/
scanf(“%d”,&n); /*输入从始发站到终点站共有几站*/
head=null;
for(i=0;i<=m;i++)
{
p2->next=p1;
p2=p1;
p1=(structticket)*malloc(len);
s1=s2=(structticket)*malloc(len); /*建立纵向链表的头结点*/
head1=s1=s2;
p1->down=s1=s2; /*指向纵向链表的头结点*/
scanf("%d","%d","%d",&p1->num,&p1->num2,&p1->time); /*输入横向链表的数据*/
for(i=0;i<=n,i++)
{
s2->next=s2;
s2=s1;
s1=(structticket)*malloc(len); /*建立纵向链表*/
scanf(“%s”,“%d”,“%d”,“%d”,“%d”,s1->name,&s1->time,&s1->money,&s1->seat,&s1->mark);
} /*输入纵向链表的数据*/
s1->next=head1; /*纵向链表为循环链表*/
}
p2->next=null;
return(head); /*返回头指针*/
gotofirst; /*返回头指针*/
}
③功能说明:
通过用户输入的数值,建立所需的结点数量.再输入每个结点的具体数据.使横向链表的尾指针指向空,纵向链表的的尾指针指向头指针.最后返回头指针,再回到用户界面.
3.Book()函数:
①程序流程图:
输入需要的车次号
输入需要到达的车站名
While循环是否需要的车次
是
横向结点值给o
While循环是否是需要的车站名
是
使mark的值为1
纵向结点值给s
纵向链表移针
横向链表移针
当横向链表下一个指针为空时
输出s点的数据
输出o点的数据
Mark是否为1
错误
否
是
②程序代码:
voidbook()
{
structticket*p;
structstation*q;
intt;
int*o,*s;
printf(“pleaseenterthenumber:
”);
scanf(“%d”,&f); /*输入需要的车次*/
printf(“pleaseenterthestation:
”);
scanf(“%d”,&h); /*输入需要到达的车站名*/
p=t; /*初始化p的值*/
while(p=!
null)
{
if(p->number==t)
{q=p->down;
o=p; /*把符合条件的横向链表结点的数据给o*/
while(q->next=!
head1)
{
if(q->name==h)
{
if(q->mark=1)
printf(“yourticketisunused”);
else
q->mark=1; /*修改mark标记*/
s=q; /*把符合条件的纵向链表的数据给s*/
}
q=q->next; /*纵向链表移针*/
}}
p=p->next; /*横向链表移针*/
}
printf(“yourtickethasalreadybooked!
”);
printf("%d","%d","%d",o->num,o->num2,o->time); /*输出横向链表的数据*/
printf(“%s”,“%d”,“%d”,“%d”,“%d”,s->name,&s->time,&s->money,&s->seat,&s->mark); /*输出纵向链表的数据*/
gotofirst;
}
③功能说明:
本函数主要是先遍历横向链表找到符合条件的结点后,转向该点的纵向链表,遍历纵向链表找到符合条件的结点,读出需要的数据.并且修改mark标记,使其成为已定车票.如果mark已经为1则输出错误信息.
3.inquire()函数:
①程序流程图:
输入需要的车次号
输入需要到达的车站名
While循环是否已到空
否
是否是需要的车次
是
While循环是否已到头指针
否
是否是需要的车站名
是
输出所需的信息
是
是
错误
移动指针
否
否
②程序代码:
voidinquire()
{
structticket*p;
structstation*q;
intt;
int*o,*s;
printf(“pleaseenterthenumber:
”);
scanf(“%d”,&f); /*输入需要的车次*/
printf(“pleaseenterthestation:
”);
scanf(“%d”,&h); /*输入需要到达的车站名*/
p=t; /*初始化p的值*/
while(p=!
null)
{
if(p->number==t)
{q=p->down;
o=p; /*把符合条件的横向链表结点的数据给o*/
while(q->next=!
head1)
{
if(q->name==h)
{
s=q; /*把符合条件的纵向链表的数据给s*/
}
q=q->next; /*纵向链表移针*/
}
}
p=p->next; /*横向链表移针*/
}
printf("%d","%d","%d",o->num,o->num2,o->time); /*输出横向链表的数据*/
printf(“%s”,“%d”,“%d”,“%d”,“%d”,s->name,&s->time,&s->money,&s->seat,&s->mark); /*输出纵向链表的数据*/
gotofirst;
}
③功能说明:
本函数主要提供查询功能.用户输入需要查询的车次和需要到车站名,程序首先遍历横向链表查找到需要的数据后转向纵向链表,接着遍历纵向链表,查找到需要的车站名.最后输出所有关于本车次的所有信息.
4.Cancel()函数:
①程序流程图:
输入需要的车次号
输入需要到达的车站名
While循环是否需要的车次
是
横向结点值给o
While循环是否是需要的车站名
是
使mark的值为0
纵向结点值给s
纵向链表移针
横向链表移针
当横向链表下一个指针为空时
输出s点的数据
输出o点的数据
②程序代码;
void cancel()
{
structticket*p;
structstation*q;
intt;
int*o,*s;
printf(“pleaseenterthenumber:
”);
scanf(“%d”,&f); /*输入需要的车次*/
printf(“pleaseenterthestation:
”);
scanf(“%d”,&h); /*输入需要到达的车站名*/
p=t; /*初始化p的值*/
while(p=!
null)
{
if(p->number=t)
{q=p->down;
o=p; /*把符合条件的横向链表结点的数据给o*/
while(q->next=!
head1)
{
if(q->name=h)
{
q->mark=0; /*修改mark标记*/
s=q; /*把符合条件的纵向链表的数据给s*/
}
q=q->next; /*纵向链表移针*/
}}
p=p->next; /*横向链表移针*/
}
printf(“yourtickethasalreadycancel!
”);
printf("%d","%d","%d",o->num,o->num2,o->time); /*输出横向链表的数据*/
printf(“%s”,“%d”,“%d”,“%d”,“%d”,s->name,&s->time,&s->money,&s->seat,&s->mark); /*输出纵向链表的数据*/
gotofirst;
}
③功能说明:
本函数主要提供退票功能.用户输入需要退票的车次和需要到车站名,程序首先遍历横向链表查找到需要的数据后转向纵向链表,接着遍历纵向链表,查找到需要的车站名.修改其mark标识是其为0.最后输出所有关于本车次的所有信息.
5.You()函数:
①程序代码:
voidyou()
{
structyou*head;
structyou*p;
p=(structyou*)malloc(len);
scanf("%d",&p->name,&p->num,&p->num1,&p->time,&p->time1);
}
gotoFirst;
}
②用户查询代码:
(注:
本函数用于管理人员查询用户)
voidfind()
{
structyou*head;
structyou*p;
intu;
scanf(“%d”,&u);
while(p=!
null)
{
if(p->num=u)
{s=p;}
p=p->next;
}
printf(“%s”,”%d”,”%d”,”%d”,”%d”,p->name,p->num,p->num1,p->time,p->time1);
}
③功能说明:
本函数用于用户输入个人信息,以便管理人员管理.而管理函数只面对管理人员使用,因此未在用户界面上显示出来.
6.统计模块:
voidtotal()
{
int*p,*q;
intn;
p=t;
while(p=!
null)
{
while(q->next=!
head1)
{
if(mark=1)
{n=n+1;}
q=q->next;
}
p=p->next;
}
printf(“thenumberofthebookedticketare:
”);
printf(“%d”,n);
}
6.所用变量声明:
①横向链表结点的结构体:
structticket
{
intnum;
intnum1;
inttime;
structticket*next;
structstation*down;
};
intt;
②纵向链表结点的结构体:
structstation
{
intname;
inttime;
intmoney;
intmark;
structstation*next;
}
③用户信息链表结点的结构体:
struct you
{
intname;
intnum;
intnum1;
inttime;
inttime1;
structyou*next;
}
四.程序说明书:
本系统用于火车站的车票管理.主要方便用户订票,也可方便管理人员管理车票.当用户看到用户界面时,可以根据提示选择自己想要的服务,选择后按下回车键,程序便会转到相应的函数进行.完成后,程序会显示您已经成功的订票或退票.完成后程序会自动回到起始位置.
管理人员也可以很方便的调用本系统包含的查询和统计函数,管理车票情况.
具体说明:
1.提示程序操作者输入预设的数据.
2.提示用户进行订票操作.
3.提示用户进行查询自己需要的车票的操作.
4.提示用户进行退票操作.
5.提示用户输入自己的相关信息.
五.程序调试:
本程序分为多模块,为的是方便小组合作.所以各个功能都由函数调用来实现.组员在各自的编制和调试中基本都实现所需的功能.但在联调的过程中,由于我们使用了大量的传递指针形的函数,所以在数值的传递上问题很多.分步执行的时候指针的位置很乱!
所以让我们遗憾的是联调并没有成功.我们也会吸取教训,在函数编制时注意数值的传递.
六.运行结果:
输入:
2
3
K717,Beijing,11:
00
Yuci,12:
00,10,0,56
Yangyuan,1:
00,20,0,56
Shijiazhuang,2:
00,30,56
输入:
k717
shijiazhuang
输出:
youhavealreadybookedtheticket!
K717,shijiazhuang,11:
00,3:
00,30,56
七.程序源代码:
#include
#include
#definenull0
#definelensizeof(structticket)
structticket
{
intnum;
intnum1;
inttime;
structticket*next;
structstation*down;
};
intt;
structstation /*公共变量声明*/
{
intname;
inttime;
intmoney;
intmark;
structstation*next;
struct you
{
intname;
intnum;
intnum1;
inttime;
inttime1;
structyou*next;
}
structticket*in() /*一个返回指针形的函数*/
{
structticket*head; /*头结点*/
structticket*p1,*p2;
structstation*s1,*s2;
intm,n;
inti;
p1=p2=(structticket*)malloc(len); /*建立横向链表的头结点*/
scanf("%d",&m); /*输入一共所需的车票信息总数*/
scanf(“%d”,&n); /*输入从始发站到终点站共有几站*/
head=null;
for(i=0;i<=m;i++)
{
p2->next=p1;
p2=p1;
p1=(structticket)*malloc(len);
s1=s2=(structticket)*malloc(len); /*建立纵向链表的头结点*/
head1=s1=s2;
p1->