数据结构模块图:
概要设计
主要模块:
1、基本模块:
Ⅰ航班信息
typedef struct node3 //含 9个信息的结构体
{
char flight[20];
char plane[20];
char add[20];
int time;
int seat;
int yseat;
ylinklist *first; //指向订票客户的指针
wqlist *front,*rear;
}node3;
node3 hbd[3]={{"LB6532","AW7518","北京 ",1,100,100,NULL,NULL,NULL},
{"MB6762","BW7517","上海 ",2,100,100,NULL,NULL,NULL},
{"NB6969","CW7516","天津 ",3,100,100,NULL,NULL,NULL}}; //初始化
用结构体数组存储有关航班的所有信息,用 first指针指向已定票客户的链表;用 front指针指向侯票客户的链表。
Ⅱ订票客户和侯票客户信息
typedef struct node1
{
char name[20];
char ID[20];
int a;
struct node1 *next1;
}ylinklist,wqlist;
己订票的客户名单可以用线性表来实现。为查找方便,线性表应按照客户姓名有序,并且为了插入和删除的方便,应以链表作为存储结构;等候替补的客户名单可以用队列来实现,但考虑到实际情况,充分利用飞机,让它不要有空余座位,也可以用线形链表来作为存储结构。
2、功能模块:
⑴打印主界面:
void scripe() //打印主界面
{
char n;
do{
printf("/n/t 欢迎使用航空客运订票系统 /n");
printf("/t+++++++++++++++++++++++++++++++++++/n");
printf("/t=>1.订票功能 2.查询功能 ==/n");
printf("/t=>3.查票功能 4.退票功能 ==/n");
printf("/t=>5.退出 ==/n");
printf("/t+++++++++++++++++++++++++++++++++++/n");
printf("/t请选择: ");
scanf("%d",&n);
switch(n){
case 1: Book(); //订票功能
break;
case 2: search(); //查询功能
break;
case 3:
Bsearch(); //查票功能
break;
case 4:
Tbook(); //退票功能
break;
default :exit(0); //退出
}
}while(n!='1'&&n!='2'&&n!='3'&&n!='4'&&n!='5');
}
打印主界面,根据用户的选择,调用相应的功能函数,进入下一个界面,调用完毕之后,又回到主界面,或者强行退出系统( exit(0))。
⑵订票功能:
void Book()
{
int d,g;
char e,N[20],I[20];
ylinklist *new1,*p,*p1;
wqlist *new2,*q,*q1;
printf(" 1、 LB6532/n 2、 MB6762/n 3、 NB6969/n") ;
printf("请输入您要选择的航班号 (1、 2、或 3)/n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
printf("%s%s%s%5d%5d%5d/n",hbd[d-1].flight,hbd[d-1].plane,hbd[d-1].add,hbd[d-1].time,hbd[d-1].seat,hbd[d-1].yseat);
printf("请问是否继续 :/n A、继续订票 /n B、侯票 /n C退出 /n");
scanf("%c",&e);
do
{
scanf("%c",&e);
}while(e!='A'&&e!='B'&&e!='C');
if(e=='A') //订票客户
{
printf("请输入以下信息 /n");
printf("您的姓名 :/n");
gets(N);
gets(N);
printf("身份证号 :/n");
gets(I);
gets(I);
printf("订票量 (1-100):/n");
scanf("%3d",&g);
new1=(ylinklist *)malloc(sizeof(ylinklist));
if(!new1)
{
printf("对不起,业务繁忙,请稍后预定 /n");
scripe();
}
else
{
strcpy(new1->name,N);
strcpy(new1->ID,I);
new1->a=g;
new1->next1=NULL;
if(hbd[d-1].first==NULL) //若原无订票客户信息
{
hbd[d-1].first=new1;
new1->next1=NULL;
}
else //原来已有订票客户
{
p=hbd[d-1].first->next1;
p1=hbd[d-1].first;
while(p!=NULL)
{
if(strcmp(new1->name,p->name)<0)//按一定的顺序插入订票客户链表
{
new1->next1=p;
p1->next1=new1;
}
else
{
p1=p;
p=p->next1;
}
}
if(p==NULL)
{
p1->next1=new1;
new1->next1=NULL;
}
}
hbd[d-1].yseat-=g;
}
printf("订票成功,欢迎再次使用 /n");
}
else if(e=='B') //侯票客户
{
printf("请输入以下信息 /n");
printf("您的姓名身份证号订票量 ");
gets(N);
gets(I);
scanf("%5d",&g);
new2=(wqlist *)malloc(sizeof(wqlist));
if(!new2)
{
printf("对不起,业务繁忙,请稍后预定 /n");
scripe();
}
strcpy(new2->name,N);
strcpy(new2->ID,I);
new2->a=g;
if(hbd[d-1].front==NULL)//若原无侯票客户信息
{
hbd[d-1].front=new2;
new2->next1=NULL; //链表的定义和入队
}
else //已有侯票客户
{
q=hbd[d-1].front->next1; //按一定的顺序插入候票客户链表
q1=hbd[d-1].front;
while(q!=NULL)
{
if(new2->a>q->a)
{
new2->next1=q;
q1->next1=new2;
}
else
{
q1=q;
q=q->next1;
}
}
if(q==NULL)
{
q1->next1=new2;
new2->next1=NULL;
}
}
}
else
scripe();
}
要订票的客户根据输入的航班号打印出来的所有有关这个航班信息,然后根据客户的选择,进入订票模块,如果订票,定义结点,并把输入的姓名、 ID和订票数量赋给结点,把结点按姓名的先后顺序插入订票客户链表中,或者是进入侯票模块,或者直接回到主界面。
⑶查询功能:
void search() //查询
{
int d;
char g;
printf("请选择您的查询方式 (1-2)/n");
printf("1、根据航班号查询 2、根据目的地查询 /n");
scanf("%d",&d);
if(d==1) hbdHsearch();
if(d==2) MDDsearch();
printf("请问是否继续 (y或 n)/n");
scanf("%c",&g);
if(g=='y') search();
if(g=='n') scripe();
}
查询功能调用两个查询函数 hbdHsearch();和 MDDsearch(),调用完毕之后,如果继续查询则调用 search();如果不是则回到主界面 scripe()。
Ⅰ根据航班号查询:
void hbdHsearch()
{
int d;
printf("请输入您的选择 (1或 2或 3)/n 1、 LB6969 2、 MB6762 3、 NB6532 /n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
printf("%s%s%s%5d%5d%5d",hbd[d-1].flight,hbd[d-1].plane,hbd[d-1].add,hbd[d-1].time,hb d[d-1].seat,hbd[d-1].yseat);
}根据用户的选择,打印他所选航班的所有信息。
Ⅱ根据目的地查询
void MDDsearch()
{
int d;
printf("请输入您的选择 (1或 2或 3)/n 1、北京 2、上海 3、天津 /n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
printf("%s%s%s%5d%5d%5d",hbd[d].flight,hbd[d].plane,hbd[d].add,hbd[d].time,hbd[d].seat,hbd[d].yseat);
}
根据用户的选择目的地,打印到达目的地的航班的所有信息。
⑷查询订票客户个人信息:
void Bsearch()
{
int d;
char Ti[20];
ylinklist *q,*p,*new1;
new1=(ylinklist *)malloc(sizeof(ylinklist)); //定义头节点
strcpy(new1->name,"");
strcpy(new1->ID,"");
new1->a=0;
new1->next1=NULL;
printf("请输入您的航班号(1或2或3)/n 1、LB6969 2、MB6762 3、NB6532 /n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
printf("请输入您的姓名");
gets(Ti);
gets(Ti);
// hbd[d-1].first=new1;
p=hbd[d-1].first;
q=NULL;
if(p==NULL)
{
printf("对不起,该航班还没有人订票/n");
scripe();
}
else
{
int num=0;
while(p!=NULL)
{
if(!strcmp((*p).name,Ti))
{
printf("%s%s%s%5d%5d%5d%s%s%5d",hbd[d-1].flight,hbd[d-1].plane,hbd[d-1].add,hbd[d-1].time,hbd[d-1].seat,hbd[d-1].yseat,(*p).name,(*p).ID,(*p).a);
num++;
}
p=p->next1;
}
if(num==0)
{
printf("您还没有订票!");
scripe();
}
}
}
查询个人订票信息,根据用户输入的航班号和自己的姓名从该航班的first指针开始查询,如果first为空,则打印“对不起,该航班还没有人订票!y(是)n(不是)” 如果用户选择y则调用 Book()函数,进入订票模块,选择n,则调用 scripe()函数,回到主界面;
如果不为空,则从first指针所指的第一个节点开始查找,寻找匹配项,如果有,则打印该客户所在航班的全部信息和客户的全部信息,否则打印“您还没有订票!则调用 scripe()函数,回到主界面。
⑸退票功能:
void TBook() //退票
{
int f;
int d,found=0;
char Ti[20];
ylinklist *q,*p;
printf("请输入您的航班号(0或1或2)/n 1、LB6969 2、MB6762 3、NB6532 /n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
p=hbd[d-1].first;//->next1;
q=hbd[d-1].first;
if(p==NULL)
{
printf("对不起,该航班还没有人订票/n");
scripe();
}
else
{
printf("请输入您的姓名/n");
gets(Ti);
gets(Ti);
printf("/n");
while(p!=NULL&&found==0)
{
if(!strcmp((*p).name,Ti))
{
printf("%s%s%s%5d%5d%5d%s%s%5d/n",hbd[d-1].flight,hbd[d-1].plane,hbd[d-1].add,hbd[d-1].time,hbd[d-1].seat,hbd[d-1].yseat,(*p).name,(*p).ID,(*p).a);
printf("请输入您的退票数量/n");
do
{
scanf("%d",&f);
}while(f>(*p).a);
if(f<=(*p).a)
{
(*p).a-=d;
hbd[d-1].yseat+=d;
if(hbd[d-1].front!=NULL) //有人侯票
{
if(hbd[d-1].yseat>hbd[d-1].front->a)
hj(d);
}//侯票客户出队,进入订票客户链表
if(f=p->a)
{
q->next1=p->next1;free(p);
printf("退票成功,欢迎再次使用/n");
scripe();
}
else q=p;p=p->next1;
}
}
}
if(p==NULL)
printf("您还没有订票!");
}
}退票模块应该说调用了查询个人订票模块,但是我不知道该怎样调用,就把整个查询个人订票函数复制到退票模块,当查询成功时,要求客户输入退票数量,当退票数量不大于他所订票的数量时,订票数量要减去退票数量,同时航班余票量也要加上退票数量,与此同时调用系统自动将满足条件的侯票客户加入到订票客户链表函数void hj(int d),并打印退票成功,如果退票数量等于订票数量时,要把该节点释放掉,调用了系统函数free(p).
⑹系统自动将满足条件的侯票客户加入到订票客户链表
void hj(int d) //候补人员进入订票客户链表
{
wqlist *p1,*q1;
p1=hbd[d-1].front->next1;
q1=hbd[d-1].front;
while(p1!=NULL)
{
if(p1->a<hbd[d-1].yseat)
{
hbd[d-1].yseat-=p1->a;
q1->next1=p1->next1;
p1->next1=hbd[d-1].first;
hbd[d-1].first=p1;
p1=q1->next1;
}
else
{
q1=p1;
p1=p1->next1;
}
}
}
系统自动将满足条件的侯票客户加入到订票客户链表模块,用while(p1!=NULL)循环将所有满足条件的预订客户的节点插入到订票客户链表中。该模块还有不足之处,虽然我后来考虑到将猴票的节点案后票的数量数从大往小排列,但这并不能解决问题,不能将选择满足条件的预订客户的节点中订票数量之和与航班余票量相差最小。这一点我是不行的!
概要设计
主要模块:
1、基本模块:
Ⅰ航班信息
typedef struct node3 //含 9个信息的结构体
{
char flight[20];
char plane[20];
char add[20];
int time;
int seat;
int yseat;
ylinklist *first; //指向订票客户的指针
wqlist *front,*rear;
}node3;
node3 hbd[3]={{"LB6532","AW7518","北京 ",1,100,100,NULL,NULL,NULL},
{"MB6762","BW7517","上海 ",2,100,100,NULL,NULL,NULL},
{"NB6969","CW7516","天津 ",3,100,100,NULL,NULL,NULL}}; //初始化
用结构体数组存储有关航班的所有信息,用 first指针指向已定票客户的链表;用 front指针指向侯票客户的链表。
Ⅱ订票客户和侯票客户信息
typedef struct node1
{
char name[20];
char ID[20];
int a;
struct node1 *next1;
}ylinklist,wqlist;
己订票的客户名单可以用线性表来实现。为查找方便,线性表应按照客户姓名有序,并且为了插入和删除的方便,应以链表作为存储结构;等候替补的客户名单可以用队列来实现,但考虑到实际情况,充分利用飞机,让它不要有空余座位,也可以用线形链表来作为存储结构。
2、功能模块:
⑴打印主界面:
void scripe() //打印主界面
{
char n;
do{
printf("/n/t 欢迎使用航空客运订票系统 /n");
printf("/t+++++++++++++++++++++++++++++++++++/n");
printf("/t=>1.订票功能 2.查询功能 ==/n");
printf("/t=>3.查票功能 4.退票功能 ==/n");
printf("/t=>5.退出 ==/n");
printf("/t+++++++++++++++++++++++++++++++++++/n");
printf("/t请选择: ");
scanf("%d",&n);
switch(n){
case 1: Book(); //订票功能
break;
case 2: search(); //查询功能
break;
case 3:
Bsearch(); //查票功能
break;
case 4:
Tbook(); //退票功能
break;
default :exit(0); //退出
}
}while(n!='1'&&n!='2'&&n!='3'&&n!='4'&&n!='5');
}
打印主界面,根据用户的选择,调用相应的功能函数,进入下一个界面,调用完毕之后,又回到主界面,或者强行退出系统( exit(0))。
⑵订票功能:
void Book()
{
int d,g;
char e,N[20],I[20];
ylinklist *new1,*p,*p1;
wqlist *new2,*q,*q1;
printf(" 1、 LB6532/n 2、 MB6762/n 3、 NB6969/n") ;
printf("请输入您要选择的航班号 (1、 2、或 3)/n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
printf("%s%s%s%5d%5d%5d/n",hbd[d-1].flight,hbd[d-1].plane,hbd[d-1].add,hbd[d-1].time,hbd[d-1].seat,hbd[d-1].yseat);
printf("请问是否继续 :/n A、继续订票 /n B、侯票 /n C退出 /n");
scanf("%c",&e);
do
{
scanf("%c",&e);
}while(e!='A'&&e!='B'&&e!='C');
if(e=='A') //订票客户
{
printf("请输入以下信息 /n");
printf("您的姓名 :/n");
gets(N);
gets(N);
printf("身份证号 :/n");
gets(I);
gets(I);
printf("订票量 (1-100):/n");
scanf("%3d",&g);
new1=(ylinklist *)malloc(sizeof(ylinklist));
if(!new1)
{
printf("对不起,业务繁忙,请稍后预定 /n");
scripe();
}
else
{
strcpy(new1->name,N);
strcpy(new1->ID,I);
new1->a=g;
new1->next1=NULL;
if(hbd[d-1].first==NULL) //若原无订票客户信息
{
hbd[d-1].first=new1;
new1->next1=NULL;
}
else //原来已有订票客户
{
p=hbd[d-1].first->next1;
p1=hbd[d-1].first;
while(p!=NULL)
{
if(strcmp(new1->name,p->name)<0)//按一定的顺序插入订票客户链表
{
new1->next1=p;
p1->next1=new1;
}
else
{
p1=p;
p=p->next1;
}
}
if(p==NULL)
{
p1->next1=new1;
new1->next1=NULL;
}
}
hbd[d-1].yseat-=g;
}
printf("订票成功,欢迎再次使用 /n");
}
else if(e=='B') //侯票客户
{
printf("请输入以下信息 /n");
printf("您的姓名身份证号订票量 ");
gets(N);
gets(I);
scanf("%5d",&g);
new2=(wqlist *)malloc(sizeof(wqlist));
if(!new2)
{
printf("对不起,业务繁忙,请稍后预定 /n");
scripe();
}
strcpy(new2->name,N);
strcpy(new2->ID,I);
new2->a=g;
if(hbd[d-1].front==NULL)//若原无侯票客户信息
{
hbd[d-1].front=new2;
new2->next1=NULL; //链表的定义和入队
}
else //已有侯票客户
{
q=hbd[d-1].front->next1; //按一定的顺序插入候票客户链表
q1=hbd[d-1].front;
while(q!=NULL)
{
if(new2->a>q->a)
{
new2->next1=q;
q1->next1=new2;
}
else
{
q1=q;
q=q->next1;
}
}
if(q==NULL)
{
q1->next1=new2;
new2->next1=NULL;
}
}
}
else
scripe();
}
要订票的客户根据输入的航班号打印出来的所有有关这个航班信息,然后根据客户的选择,进入订票模块,如果订票,定义结点,并把输入的姓名、 ID和订票数量赋给结点,把结点按姓名的先后顺序插入订票客户链表中,或者是进入侯票模块,或者直接回到主界面。
⑶查询功能:
void search() //查询
{
int d;
char g;
printf("请选择您的查询方式 (1-2)/n");
printf("1、根据航班号查询 2、根据目的地查询 /n");
scanf("%d",&d);
if(d==1) hbdHsearch();
if(d==2) MDDsearch();
printf("请问是否继续 (y或 n)/n");
scanf("%c",&g);
if(g=='y') search();
if(g=='n') scripe();
}
查询功能调用两个查询函数 hbdHsearch();和 MDDsearch(),调用完毕之后,如果继续查询则调用 search();如果不是则回到主界面 scripe()。
Ⅰ根据航班号查询:
void hbdHsearch()
{
int d;
printf("请输入您的选择 (1或 2或 3)/n 1、 LB6969 2、 MB6762 3、 NB6532 /n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
printf("%s%s%s%5d%5d%5d",hbd[d-1].flight,hbd[d-1].plane,hbd[d-1].add,hbd[d-1].time,hb d[d-1].seat,hbd[d-1].yseat);
}根据用户的选择,打印他所选航班的所有信息。
Ⅱ根据目的地查询
void MDDsearch()
{
int d;
printf("请输入您的选择 (1或 2或 3)/n 1、北京 2、上海 3、天津 /n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
printf("%s%s%s%5d%5d%5d",hbd[d].flight,hbd[d].plane,hbd[d].add,hbd[d].time,hbd[d].seat,hbd[d].yseat);
}
根据用户的选择目的地,打印到达目的地的航班的所有信息。
⑷查询订票客户个人信息:
void Bsearch()
{
int d;
char Ti[20];
ylinklist *q,*p,*new1;
new1=(ylinklist *)malloc(sizeof(ylinklist)); //定义头节点
strcpy(new1->name,"");
strcpy(new1->ID,"");
new1->a=0;
new1->next1=NULL;
printf("请输入您的航班号(1或2或3)/n 1、LB6969 2、MB6762 3、NB6532 /n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
printf("请输入您的姓名");
gets(Ti);
gets(Ti);
// hbd[d-1].first=new1;
p=hbd[d-1].first;
q=NULL;
if(p==NULL)
{
printf("对不起,该航班还没有人订票/n");
scripe();
}
else
{
int num=0;
while(p!=NULL)
{
if(!strcmp((*p).name,Ti))
{
printf("%s%s%s%5d%5d%5d%s%s%5d",hbd[d-1].flight,hbd[d-1].plane,hbd[d-1].add,hbd[d-1].time,hbd[d-1].seat,hbd[d-1].yseat,(*p).name,(*p).ID,(*p).a);
num++;
}
p=p->next1;
}
if(num==0)
{
printf("您还没有订票!");
scripe();
}
}
}
查询个人订票信息,根据用户输入的航班号和自己的姓名从该航班的first指针开始查询,如果first为空,则打印“对不起,该航班还没有人订票!y(是)n(不是)” 如果用户选择y则调用 Book()函数,进入订票模块,选择n,则调用 scripe()函数,回到主界面;
如果不为空,则从first指针所指的第一个节点开始查找,寻找匹配项,如果有,则打印该客户所在航班的全部信息和客户的全部信息,否则打印“您还没有订票!则调用 scripe()函数,回到主界面。
⑸退票功能:
void TBook() //退票
{
int f;
int d,found=0;
char Ti[20];
ylinklist *q,*p;
printf("请输入您的航班号(0或1或2)/n 1、LB6969 2、MB6762 3、NB6532 /n");
do
{
scanf("%d",&d);
}while(d!=1&&d!=2&&d!=3);
p=hbd[d-1].first;//->next1;
q=hbd[d-1].first;
if(p==NULL)
{
printf("对不起,该航班还没有人订票/n");
scripe();
}
else
{
printf("请输入您的姓名/n");
gets(Ti);
gets(Ti);
printf("/n");
while(p!=NULL&&found==0)
{
if(!strcmp((*p).name,Ti))
{
printf("%s%s%s%5d%5d%5d%s%s%5d/n",hbd[d-1].flight,hbd[d-1].plane,hbd[d-1].add,hbd[d-1].time,hbd[d-1].seat,hbd[d-1].yseat,(*p).name,(*p).ID,(*p).a);
printf("请输入您的退票数量/n");
do
{
scanf("%d",&f);
}while(f>(*p).a);
if(f<=(*p).a)
{
(*p).a-=d;
hbd[d-1].yseat+=d;
if(hbd[d-1].front!=NULL) //有人侯票
{
if(hbd[d-1].yseat>hbd[d-1].front->a)
hj(d);
}//侯票客户出队,进入订票客户链表
if(f=p->a)
{
q->next1=p->next1;free(p);
printf("退票成功,欢迎再次使用/n");
scripe();
}
else q=p;p=p->next1;
}
}
}
if(p==NULL)
printf("您还没有订票!");
}
}退票模块应该说调用了查询个人订票模块,但是我不知道该怎样调用,就把整个查询个人订票函数复制到退票模块,当查询成功时,要求客户输入退票数量,当退票数量不大于他所订票的数量时,订票数量要减去退票数量,同时航班余票量也要加上退票数量,与此同时调用系统自动将满足条件的侯票客户加入到订票客户链表函数void hj(int d),并打印退票成功,如果退票数量等于订票数量时,要把该节点释放掉,调用了系统函数free(p).
⑹系统自动将满足条件的侯票客户加入到订票客户链表
void hj(int d) //候补人员进入订票客户链表
{
wqlist *p1,*q1;
p1=hbd[d-1].front->next1;
q1=hbd[d-1].front;
while(p1!=NULL)
{
if(p1->a<hbd[d-1].yseat)
{
hbd[d-1].yseat-=p1->a;
q1->next1=p1->next1;
p1->next1=hbd[d-1].first;
hbd[d-1].first=p1;
p1=q1->next1;
}
else
{
q1=p1;
p1=p1->next1;
}
}
}
系统自动将满足条件的侯票客户加入到订票客户链表模块,用while(p1!=NULL)循环将所有满足条件的预订客户的节点插入到订票客户链表中。该模块还有不足之处,虽然我后来考虑到将猴票的节点案后票的数量数从大往小排列,但这并不能解决问题,不能将选择满足条件的预订客户的节点中订票数量之和与航班余票量相差最小。这一点我是不行的!