实习五 航空订票系统

一、需求分析

1.问题描述:

 试设计一个航空订票系统,基本要求如下:

每条航班所涉及的信息有:航班号,航班机型,起飞机场,降落机场,日期(星期几),起飞时间,降落时间,飞行时长,各等级的价格、乘员定额、余票量,订定票的客户名单(包括姓名,订票量,舱位等级(头等舱、公务舱、经济舱))以及等候替补的客户名单(包括姓名、所需数量)。采用链式存储结构。

2.基本要求:                        

(1)航班信息管理。

(2)查询航线,按以下几种方式查询:

① 按航班号查询;

② 按起点站查询;

③ 按终点站查询;

④ 按日期查询;

每种查询方式中,查询后输出如下信息:航班号,航班机型,起飞机场,降落机场,日期(星期几),起飞时间,降落时间,飞行时长,价格,余票量。

(3)承办订票业务:根据客户提出的要求(航班号,订票数额)查询该航班票额情况,若有余票,则为客户办理订票手续,并输出座位号;若已满员或余票少于订票额,则需重新询问客户要求。若需要,可登记排队候补。

(4)承办退票业务:根据客户提出的情况(日期,航班号),为客户办理退票手续,然后查询该航班是否有人排队候补,首先询问排在第一的客户,若所退票额能满足他的要求,则为他办理订票手续,否则依次询问其它排队候补的客户。

https://wenku.baidu.com/view/c91fa69f6bdc5022aaea998fcc22bcd127ff4245
#include<stdio.h>
#include<malloc.h>
#include<string.h>
#define MaxStackSize 100      //票数
typedef int Datetype;
typedef struct pnode        //链式等票队列结点
{
    char name[20];
    int np;
    struct pnode *next;
}LPNode;
typedef struct              //链式队列结点指针
{
    LPNode *front;
    LPNode *rear;
    int count;
}LPQueue;

typedef struct
{
    char name[20];
    int number;
    int biaoji;
}Ticketmessage;//机票信息结构体
typedef struct
{
    Datetype fnumber;  //航班号
    int plane;   //航班机型
    char sairport[20];//起飞机场
    char eairport[20];//降落机场
    int day;//日期(星期几)
    int stime;//起飞时间
    int etime;//降落时间
    int ltime;//飞行时间
    int jpshu;//机票数
    int tdjps;//头等舱机票数
    int swjps;//商务舱机票数
    int jjjps;//经济舱机票数
    int tdjia;
    int swjia;
    int jjjia;

    Ticketmessage ticket[MaxStackSize];//机票数组
    LPQueue Q;
}Airmessage;                //航班信息结构体
typedef struct qnode        //链式航班队列结点
{
    Airmessage Air;
    struct qnode *next;
}LQNode;


int menu();//函数声明
int menu1();
int menu2();



void ListInitiate(LQNode **head)//航班链表的初始化
{
    *head=(LQNode *)malloc(sizeof(LQNode));
    (*head)->next=NULL;
}
void JListInitiate(LQNode *q)//机票座位及标记初始化
{
    int i;
    for(i=0;i<q->Air.jpshu;i++)
    {
        q->Air.ticket[i].number=i+1;//座位编号
        q->Air.ticket[i].biaoji=0; //表示机票该座位未被预订
    }
    q->Air.Q.rear=NULL;           //初始化队列
    q->Air.Q.front=NULL;
    q->Air.Q.count=0;
}


int message(LQNode *head)//存储航班信息的线性表
{
    int i,n;
    LQNode *q,*p;
    p=head;
    printf("\t\t输入航班数:");
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        printf("\t\t输入的第%d航班信息:",i+1);
        q=(LQNode *)malloc(sizeof(LQNode));
        printf("\n\t\t1.航班号,2.航班机型,3.起飞机场,4.降落机场,5.日期(星期几):\n\t\t");
        scanf("%d %d %s %s %d",&q->Air.fnumber,&q->Air.plane,q->Air.sairport,q->Air.eairport,&q->Air.day);//MaxStackSize
        printf("\t\t6起飞时间,7降落时间,8头等舱机票数,9商务舱机票数,10经济舱机票数\n\t\t");
        scanf("%d %d %d %d %d",&q->Air.stime,&q->Air.etime,&q->Air.tdjps,&q->Air.swjps,&q->Air.jjjps);
        printf("\t\t11头等舱价格,12商务舱价格,13经济舱价格\n\t\t");
        scanf("%d %d %d",&q->Air.tdjia,&q->Air.swjia,&q->Air.jjjia);

        q->Air.jpshu=q->Air.tdjps+q->Air.swjps+q->Air.jjjps;
        q->Air.ltime=q->Air.etime-q->Air.stime;
        p->next=q;
        p=q;
        p->next=NULL;
        JListInitiate(q);
        //HPrintf(p);
    }
    menu1(head);
    return 0;
}
int Dlmessage(LQNode *head)//删除航班信息
{
    int k=1;
    LQNode *p,*s;
    int xnumber;
    printf("\n\t\t请输入航班号:");
    scanf("%d",&xnumber);
    p=head;
    while(p->next!=NULL&&p->next->next!=NULL)
    {
        if(xnumber==p->next->Air.fnumber)
        {
            s=p->next;
            p->next=p->next->next;
            free(s);
            k=0;
        }
        p=p->next;
    }
    if(p->next!=NULL&&xnumber==p->next->Air.fnumber)
    {
        s=p->next;
        p->next=NULL;
        free(s);
        k=0;
    }
    if(k)printf("\t\t无此航班!请重试!!\n");
    menu1(head);
    return 0;
}
int Ismessage(LQNode *head)//链表后插入航班信息
{
    LQNode *p,*q;
    p=head;
    q=(LQNode *)malloc(sizeof(LQNode));
    printf("\n\t\t请依次输入下列航班信息");
    printf("\n\t\t1.航班号,2.航班机型,3.起飞机场,4.降落机场,5.日期(星期几):");
    scanf("%d %d %s %s %d",&q->Air.fnumber,&q->Air.plane,q->Air.sairport,q->Air.eairport,&q->Air.day);//MaxStackSize
    printf("\t\t6.起飞时间,7.降落时间,8头等舱机票数,9商务舱机票数,10经济舱机票数:");
    scanf("%d %d %d %d %d",&q->Air.stime,&q->Air.etime,&q->Air.tdjps,&q->Air.swjps,&q->Air.jjjps);

    printf("\t\t11头等舱价格,12商务舱价格,13经济舱价格\n\t\t");
    scanf("%d %d %d",&q->Air.tdjia,&q->Air.swjia,&q->Air.jjjia);

    q->Air.jpshu=q->Air.tdjps+q->Air.swjps+q->Air.jjjps;
    q->Air.ltime=q->Air.etime-q->Air.stime;
    q->next=NULL;
    while(p->next!=NULL)p=p->next;
    p->next=q;
    JListInitiate(q);//机票座位及标记初始化函数
    menu1(head);
    return 0;
}
int Chmessage(LQNode *head)//链表中修改航班信息
{
    int xnumber;
    int k;
    //int x;
    //char ax[20];
    LQNode *p,*q;
    p=head;
    printf("\t\t请输入要修改信息的航班号:");
    scanf("%d",&xnumber);

        while(p->next!=NULL)
    {
        if(p->next->Air.fnumber==xnumber)
        {
            HPrintf(p->next);
            break;
        }
        else p=p->next;
    }
    printf("\t\t请输入要修改信息前的序号:");
    scanf("%d",&k);
    switch(k)
    {
        case 1:{printf("\t\t请输入修改后的航班号:");scanf("%d",&p->next->Air.fnumber);break;}
        case 2:{printf("\t\t请输入修改后的航班机型:");scanf("%d",&p->next->Air.plane);break;}
        case 3:{printf("\t\t请输入修改后的起飞机场:");scanf("%s",p->next->Air.sairport);break;}
        case 4:{printf("\t\t请输入修改后的降落机场:");scanf("%s",p->next->Air.eairport);break;}
        case 5:{printf("\t\t请输入修改后的日期(星期):");scanf("%d",&p->next->Air.day);break;}
        case 6:{printf("\t\t请输入修改后的起飞时间:");scanf("%d",&p->next->Air.stime);break;}
        case 7:{printf("\t\t请输入修改后的降落时间:");scanf("%d",&p->next->Air.etime);break;}
        case 8:{printf("\t\t请输入修改后的头等舱机票数:");scanf("%d",&p->next->Air.tdjps);break;}
        case 9:{printf("\t\t请输入修改后的商务舱机票数:");scanf("%d",&p->next->Air.swjps);break;}
        case 10:{printf("\t\t请输入修改后的经济舱机票数:");scanf("%d",&p->next->Air.jjjps);break;}
    }
    if(k==6||k==7)p->next->Air.ltime=p->next->Air.etime-p->next->Air.stime;
    if(k==8||k==9||k==10)p->next->Air.jpshu=p->next->Air.tdjps+p->next->Air.swjps+p->next->Air.jjjps;
    menu1(head);
    return 0;
}
int Semessage(LQNode *head)//航班查询
{
    LQNode *p;
    p=head;
    while(p->next!=NULL)
    {
        HPrintf(p->next);
        p=p->next;
    }
    menu1(head);
    return 0;
}
int Qumessage(LQNode *head)
{
    LPNode *q;
    LQNode *p;
    p=head;
    int xnumber;
    printf("\t\t请输入航班号查询:");
    scanf("%d",&xnumber);
    while(p->next!=NULL&&p->next->Air.fnumber!=xnumber)p=p->next;
    if(p->next->Air.Q.front!=NULL)
    printf("\t\t排队等票人姓名及票数:");
    else printf("\t\t无排队等票的人!!!");
    q=p->next->Air.Q.front;
    while(q!=NULL)
    {
        printf("%s: %d ",q->name,q->np);//
        q=q->next;
    }
    menu3(head);
    return 0;
}
int Cxmessage(LQNode *head)
{
    int i=0;
    int xnumber;
    LQNode *p;
    p=head;
    printf("\t\t请输入航班号查询:");
    scanf("%d",&xnumber);
    while(p->next!=NULL&&p->next->Air.fnumber!=xnumber)p=p->next;
    printf("\t\t订票人姓名及座位号如下:");
    while(i<p->next->Air.jpshu)
    {
        if(p->next->Air.ticket[i].biaoji==1)
        printf("%s:%d  ",p->next->Air.ticket[i].name,i+1);
        i++;
    }
    //printf("\n");
    menu3(head);
    return 0;
}
int QueueAppend(LQNode *p,char xname[],int x) //入队列等票函数
 {
     // printf("\n\n%s",name);
    //LQNode *p;航班
     LPNode *d;  // printf("\n\n%s",xname);//机票
    d=(LPNode *)malloc(sizeof(LPNode));
    //printf("\n\n%s",name);
    //strncpy(d->dticket->name,name,sizeof(d->dticket->name));//d->dticket->name[sizeof(d->dticket->name)-1]='\0';printf("\n\n%s",name);//*******************************************
    //memcpy(d->dticket->name,xname,3);
    strcpy(d->name,xname);
    d->np=x;
                               //////////////////////////////////////////////////////////////////////////
    //d->dticket->name=name;
                                               // printf("\n\n%s %s",d->name,xname);
    d->next=NULL;
    p->next->Air.Q.count++;
                                               // printf("\n\n%d",p->next->Air.Q.count);
   // while(p->next!=NULL&&p->Air.fnumber!=number)p=p->next;
    if(p->next->Air.Q.front==NULL)p->next->Air.Q.front=d;//可行
    if(p->next->Air.Q.rear!=NULL)p->next->Air.Q.rear->next=d;
    p->next->Air.Q.rear=d;
                                              //printf("\n\n%s",p->next->Air.Q.front->name);
    //free(d);
    return 0;
 }
int Dingpiao(LQNode *head)
{
    int i,j,k,m,n;
    int number;
    int xnp;
    //Ticketmessage *tx;
    char xname[20];
    LQNode *p;
    p=head;
    //tx=NULL;
    printf("\t\t请输入航班号:");
    scanf("%d",&number);
    while(p->next!=NULL&&p->next->Air.fnumber!=number)p=p->next;
    if(p->next==NULL)
    {
        printf("\t\t无此航班号!请重新输入\n");
        Dingpiao(head);
    }
    else
    {
        printf("\t\t请输入姓名(拼音)和票数:");
        scanf("%s %d",xname,&xnp);
        i=0;
        j=0;
        while(i<p->next->Air.jpshu)//MaxStackSize
        {
            if(p->next->Air.ticket[i].biaoji==0)j++;//机票是否都售完
        //printf("%d\n",p->Air.ticket[i].biaoji);
            i++;
        }//数余票


        /*i=0;
        while(i<p->next->Air.jpshu&&p->next->Air.ticket[i].biaoji==1)i++;
            //printf("\n\n%s %s",p->next->Air.ticket[i].name,xname);
            if(strcmp(p->next->Air.ticket[i].name,xname)==0)
            {
                printf("\n\t\t实名制订票,你已定过票!!!\n");
                menu(head);
                return 0;
                   int i,j;

            }*/

        if(j==0)//MaxStackSize
        {
            printf("\t\t该航班无余票,请耐心等待!\n");
            QueueAppend(p,xname,xnp);//printf("\t该航班无余票,请耐心等待!\n");
        }
        else if(j>=xnp)
        {
            //j-=xnp;
            for(m=0;m<xnp;m++)
            {
                printf("\t\t你有下列座位号可选:");
                for(i=0;i<p->next->Air.jpshu;i++)
                if(p->next->Air.ticket[i].biaoji==0) printf("%d ",i+1);
                printf("\n\t\t座位号1~%d头等舱 %d~%d公务舱 %d~%d经济舱",p->next->Air.tdjps,p->next->Air.tdjps+1,p->next->Air.swjps+p->next->Air.tdjps,p->next->Air.jpshu-p->next->Air.jjjps+1,p->next->Air.jpshu);
                printf("\n\t\t你选择座位号:");
                scanf("%d",&k);
                strcpy(p->next->Air.ticket[k-1].name,xname);
                p->next->Air.ticket[k-1].biaoji=1;
            }

        /*for(i=0;i<MaxStackSize;i++)    //剔除被选中的座位号
            if(p->Air.ticket[i].number==k)
            {
                p->Air.ticket[i].biaoji==1;
                p->Air.ticket[i].name==name;
            }*/
        }
        else
        {
            printf("\t\t余票不足!输入1先定部分机票,输入0则等票!:");
            scanf("%d",&n);
            if(n)BfDingpiao(p,xname,xnp-j);
            else QueueAppend(p,xname,xnp);           //入队列等待
        }
    }
    //printf("\n");
    menu3(head);
    return 0;
}
 int BfDingpiao(LQNode *p,char a[],int j)//j为等待订票数
 {
    int i=0;
    printf("\t\t你的座位号为:");
    while(i<p->next->Air.jpshu)
    {
        if(p->next->Air.ticket[i].biaoji==0)
        {
            printf("%d ",i+1);
            p->next->Air.ticket[i].biaoji=1;
            strcpy(p->next->Air.ticket[i].name,a);
        }
    i++;
    }
    QueueAppend(p,a,j);
    return 0;
 }
 int QueueGet(LQNode *p)    //出队列订票
 {
    int i,k,j,m,n;
    LPNode *q,*r;
    n=0; //判断是否需要向队列依次询问订票
    j=0;
    p=p->next;

     q=p->Air.Q.front;
     for(i=0;i<p->Air.jpshu;i++)//MaxStackSize
    if(p->Air.ticket[i].biaoji==0)j++;
    while(q!=NULL&&n==0)//还有机票
    {
        printf("\t\t姓名(拼音) 预订票数:%s %d\n",q->name,q->np);
        if(j>=q->np)
        {
           // printf("\n\n%d",j);
           // printf("\n\n%d",q->np);
            p->Air.Q.count--;
            for(m=0;m<q->np;m++)
            {
                printf("\t\t你有下列座位号可选:");
                for(i=0;i<p->Air.jpshu;i++)
                if(p->Air.ticket[i].biaoji==0) printf("%d ",i+1);
                printf("\n\t\t座位号1~%d头等舱 %d~%d公务舱 %d~%d经济舱",p->Air.tdjps,p->Air.tdjps+1,p->Air.swjps+p->Air.tdjps,p->Air.jpshu-p->Air.jjjps+1,p->Air.jpshu);
                printf("\n\t\t你选择座位号:");
                scanf("%d",&k);
                strcpy(p->Air.ticket[k-1].name,q->name);
                p->Air.ticket[k-1].biaoji=1;
            }
            if(q==p->Air.Q.front)p->Air.Q.front=p->Air.Q.front->next;//出队列第一个结点
            else //出队列
            {
                r=p->Air.Q.front;
                while(r->next !=NULL&& strcmp(p->Air.ticket[k-1].name,r->next->name)!=0)r=r->next;
                r->next=r->next->next;
            }
            if(j==q->np)n=1;//不用再出队列
            else {n=0;j-=q->np;q=q->next;}//还要出队列
           // printf("\n\n%d",j);
        }
        else
        {
            printf("\t\t余票不足!输入1先定部分机票,输入0则等票!:");
            scanf("%d",&n);
            if(n)
            {
                i=0;
                printf("\t\t你的座位号为:");
                while(i<p->Air.jpshu)
                {
                   if(p->Air.ticket[i].biaoji==0)
                    {
                     printf("%d ",i+1);
                     p->Air.ticket[i].biaoji=1;
                     strcpy(p->Air.ticket[i].name,q->name);
                    }
                    i++;
                }
                printf("\n");
                q->np-=j;
            }
            else q=q->next;      //n==0在队列中等待,并向后询问
        }
        //if(n==1&&)q=q->next;     //还有余票
    }
    return 0;
 }




int Tuipiao(LQNode *head)
{
    int i,j,n,m;
    j=0;
    int number;
    char name[20];
    LQNode *p;//航班
    p=head;
    printf("\t\t请输入航班号:");
    scanf("%d",&number);
    while(p->next!=NULL&&p->next->Air.fnumber!=number)p=p->next;
    printf("\t\t请输入姓名(拼音):");
    scanf("%s",name);
    for(i=0;i<p->next->Air.jpshu;i++)//MaxStackSize
    if(strcmp(p->next->Air.ticket[i].name,name)==0)j++;
    if(j>1)
    {
        printf("\t\t你订了%d张机票,其座位号分别为:",j);
        for(i=0;i<p->next->Air.jpshu;i++)//MaxStackSize
        if(strcmp(p->next->Air.ticket[i].name,name)==0)
        printf("%d ",i+1);
        printf("\n\t\t请输入退票数:");
        scanf("%d",&n);
        printf("\t\t请输入退票的座位号:");
        for(i=0;i<n;i++)
        {
            scanf("%d",&m);
            p->next->Air.ticket[m-1].biaoji=0;
         }
    }
    else if(j==1)
    {
        printf("\t\t请输入退票的座位号:");
        scanf("%d",&m);
        p->next->Air.ticket[m-1].biaoji=0;
    }
    //printf("\n\n%s %s",p->Air.ticket[i].name,name);
    //printf("%d",strcmp(p->next->Air.ticket[i].name,name));

       //printf("%d\n",p->next->Air.Q.count);
    //printf("\n\n%s",p->next->Air.Q.front->name);



    if(p->next->Air.Q.count!=0)QueueGet(p);//调用出队列函数(已确定航班)

    menu(head);
    return 0;
}

int HPrintf(LQNode *p)
{
    int i,j;
    i=0;
    j=0;
    while(i<p->Air.jpshu)//MaxStackSize
    {
        if(p->Air.ticket[i].biaoji==0)j++;//机票是否都售完
        //printf("%d\n",p->Air.ticket[i].biaoji);
        i++;
    }
    printf("\t\t1.航班号,2.航班机型,3.起飞机场,4.降落机场,5.日期");
    printf("\n\t\t");
    printf("%d ",p->Air.fnumber);
    printf("%d ",p->Air.plane);
    printf("%s ",p->Air.sairport);
    printf("%s ",p->Air.eairport);
    printf("%d\n",p->Air.day);
    printf("\t\t6.起飞时间,7.降落时间,8余票量,飞行时长");
    printf("\n\t\t");
    printf("%d ",p->Air.stime);
    printf("%d ",p->Air.etime);
    printf("%d ",j);
    printf("%d\n",p->Air.ltime);
    printf("\t\t11头等舱价格,12商务舱价格,13经济舱价格");
    printf("\n\t\t");
    printf("%d ",p->Air.tdjia);
    printf("%d ",p->Air.swjia);
    printf("%d\n",p->Air.jjjia);
        //scanf("%d %d %d",&q->Air.tdjia,&q->Air.swjia,&q->Air.jjjia);

    //printf("($%d $%d $%d)\n",DJ1,DJ2,DJ3);
}
int HbSearch(LQNode *head)//航班
{
    LQNode *p;
    int xnumber;

    printf("\n\t\t请输入航班号:");
    scanf("%d",&xnumber);
    p=head;
    while(p!=NULL)
    {
        if(xnumber==p->Air.fnumber)HPrintf(p);
        p=p->next;
    }
    menu2(head);
    return 0;
}

int SaSearch(LQNode *head)//起点
{
    LQNode *p;
    char xsa[20];
    p=head;
    printf("\t\t请输入起点站:");
    scanf("%s",xsa);
    while(p!=NULL)
    {
        if(strcmp(xsa,p->Air.sairport)==0)HPrintf(p);
        p=p->next;
    }
    menu2(head);
    return 0;
}
int EaSearch(LQNode *head)//终点
{
    LQNode *p;
    char xea[20];
    p=head;
    printf("\t\t:请输入终点站");
    scanf("%s",xea);
    while(p!=NULL)
    {
        if(strcmp(xea,p->Air.eairport)==0)HPrintf(p);
        p=p->next;
    }
    menu2(head);
    return 0;
}
int TmSearch(LQNode *head)//日期
{
    LQNode *p;
    int xday;
    p=head;
    printf("\t\t请输入日期(星期):");
    scanf("%d",xday);
    while(p!=NULL)
    {
        if(p->Air.day==xday)HPrintf(p);
        p=p->next;
    }
    menu2(head);
    return 0;
}

int menu1(LQNode *head)
{
    int yw;
    printf("\n\t\t           1.载入航班\n");
    printf("\t\t           2.删除航班\n");
    printf("\t\t           3.插入航班\n");
    printf("\t\t           4.查询航班\n");
    printf("\t\t           5.修改航班\n");
    printf("\t\t           0.返回\n");
    printf("\t\t请选择输入航班信息前的序号(0 1 2 3 4 5):");
    scanf("%d",&yw);
    while((yw<0||yw>5))//输入不合法
    {
        printf("\t\t********暂无此项业务,请重新输入:");
        scanf("%d",&yw);
    }
    switch(yw)
    {
        case 1:  message(head);break;
        case 2:  Dlmessage(head);break;
        case 3: Ismessage(head);break;
        case 4: Semessage(head);break;
        case 5: Chmessage(head);break;
        case 0: menu(head);break;
    }
    return 0;
}
int menu2(LQNode *head)
{
    int yw;
    printf("\n\t\t           1.按航班号查询      \n");
    printf("\t\t           2.按起点站查询      \n");
    printf("\t\t           3.按终点站查询      \n");
    printf("\t\t           4.按日期查询        \n");
    printf("\t\t           0.返回              \n");
    printf("\t\t请选择输入航班信息前的序号(0 1 2 3 4):");
    scanf("%d",&yw);
    while((yw<0||yw>4))//输入不合法
    {
        printf("\t\t********暂无此项业务,请重新输入:");
        scanf("%d",&yw);
    }
    switch(yw)
    {
        case 1:  HbSearch(head);break;
        case 2:  SaSearch(head);break;
        case 3:  EaSearch(head);break;
        case 4:  TmSearch(head);break;
        case 0:  menu(head);break;
    }
    return 0;
}
int menu3(LQNode *head)
{
    int yw;
    printf("\n\t\t           1.办理订票业务      \n");
    printf("\t\t           2.排队等票信息      \n");
    printf("\t\t           3.查询订票信息      \n");
    printf("\t\t           0.返回              \n");
    printf("\t\t请选择输入业务前的序号(0 1 2 3):");
    scanf("%d",&yw);
    while((yw<0||yw>3))//输入不合法
    {
        printf("\t\t********暂无此项业务,请重新输入:");
        scanf("%d",&yw);
    }
    switch(yw)
    {
        case 1:  Dingpiao(head);break;
        case 2:  Qumessage(head);break;
        case 3:  Cxmessage(head);break;
        case 0:  menu(head);break;
    }
    return 0;

}





int menu(LQNode *head)
{
    int yw;
    printf("\n\t\t********###航空订票系统#####********\n");
    printf("\t\t***********               **********\n");
    printf("\t\t########## 1.航班信息管理  #########\n");
    printf("\t\t########## 2.航线查询业务  #########\n");
    printf("\t\t########## 3.承办订票业务  #########\n");
    printf("\t\t########## 4.承办退票业务  #########\n");
    printf("\t\t########## 0.退出系统      #########\n");
    printf("\t\t***********               **********\n");
    printf("\t\t********请选择输入业务前的序号: ");
    scanf("%d",&yw);
    while((yw<0||yw>4))
    {                      //输入不合法
        printf("\t\t********暂无此项业务,请重新输入:");
        scanf("%d",&yw);
    }
    switch(yw)
    {
        case 1:  menu1(head);break;
        case 2:  menu2(head);break;
        case 3:  menu3(head);break;
        case 4:  Tuipiao(head);break;
        case 0: return 0;
    }
    return 0;
}
int main()
{
    LQNode *head;

    ListInitiate(&head);

    menu(head);
    return 0;
}

                                                           3.航空订票系统

一、需求分析

1.问题描述:

 试设计一个航空订票系统,基本要求如下:

每条航班所涉及的信息有:航班号,航班机型,起飞机场,降落机场,日期(星期几),起飞时间,降落时间,飞行时长,各等级的价格、乘员定额、余票量,订定票的客户名单(包括姓名,订票量,舱位等级(头等舱、公务舱、经济舱))以及等候替补的客户名单(包括姓名、所需数量)。采用链式存储结构。

2.基本要求:                        

(1)航班信息管理。

(2)查询航线,按以下几种方式查询:

① 按航班号查询;

② 按起点站查询;

③ 按终点站查询;

④ 按日期查询;

每种查询方式中,查询后输出如下信息:航班号,航班机型,起飞机场,降落机场,日期(星期几),起飞时间,降落时间,飞行时长,价格,余票量。

(3)承办订票业务:根据客户提出的要求(航班号,订票数额)查询该航班票额情况,若有余票,则为客户办理订票手续,并输出座位号;若已满员或余票少于订票额,则需重新询问客户要求。若需要,可登记排队候补。

(4)承办退票业务:根据客户提出的情况(日期,航班号),为客户办理退票手续,然后查询该航班是否有人排队候补,首先询问排在第一的客户,若所退票额能满足他的要求,则为他办理订票手续,否则依次询问其它排队候补的客户。

                       

二、设计

      1. 设计思想

        (1)存储结构

          以线性表模拟航班,用链表实现;

以足够大的数组模拟航班的机票,用顺序结构实现;

以队列模拟等候预定机票,用链表实现。

        (2)主要算法基本思想

          该航空订票系统没有很难的算法,其基本框架均由链式线性表,顺序数组和链式队列的基本操作组成。

1.链式线性表的初始化,创建,插入,修改,删除,查找

2.顺序数组保存座位号的初始化,元素的删除,插入。

3.链式队列的出队列操作和入队列操作。

        各功能之间的相互衔接将在详细算法中介绍。

    2. 设计表示

        (1)函数调用关系图

          main→ListInitiate→menu1→message→Dlmessage→Ismessage

         →Chmessage→Semessage       

main→menu2→HbSearch→SaSearch→EaSearch→TmSearch →HPrintf       main→menu3→Dingpiao→Qumessage→Cxmessage

               

(2)函数接口规格说明

        int menu(LQNode *head)  //以head为头指针的航班线性表的主菜单

        int menu1(LQNode *head) //以head为头指针的航班线性表的航班信息管理菜单

        int menu2(LQNode *head) //以head为头指针的航班线性表的航线查新菜单

       int menu3(LQNode *head) //以head为头指针的航班线性表的订票业务菜单

       int message(LQNode *head)//存储航班信息的线性表

      int Dlmessage(LQNode *head)//删除航班信息

      int Ismessage(LQNode *head)//链表后插入航班信息

int Chmessage(LQNode *head)//链表中修改航班信息

int Semessage(LQNode *head)//航班查询

int HbSearch(LQNode *head)//航班

int SaSearch(LQNode *head)//起点

int EaSearch(LQNode *head)//终点

int TmSearch(LQNode *head)//日期

int Dingpiao(LQNode *head)//订票业务

int Qumessage(LQNode *head)//排队等票

int Cxmessage(LQNode *head)//查询订票信息

3. 详细设计(主要函数)

#define MaxStackSize 100      //最大的票数

typedef int Datetype;

typedef struct pnode        //链式等票队列结点

{

    char name[20];

    int np;

    struct pnode *next;

}LPNode;

typedef struct              //链式队列结点指针

{

    LPNode *front;

    LPNode *rear;

    int count;

}LPQueue;

typedef struct

{

    char name[20];

    int number;

    int biaoji;

}Ticketmessage;//机票信息结构体

typedef struct

{

    Datetype fnumber;  //航班号

    int plane;   //航班机型

    char sairport[20];//起飞机场

    char eairport[20];//降落机场

    int day;//日期(星期几)

    int stime;//起飞时间

    int etime;//降落时间

    int ltime;//飞行时间

    int jpshu;//机票数

    int tdjps;//头等舱机票数

    int swjps;//商务舱机票数

    int jjjps;//经济舱机票数

    int tdjia;//头等舱价格

    int swjia;//商务舱价格

    int jjjia;//经济舱价格

    Ticketmessage ticket[MaxStackSize];//机票数组

    LPQueue Q;  //等票队列

}Airmessage;                //航班信息结构体

typedef struct qnode        //链式航班队列结点

{

    Airmessage Air;

    struct qnode *next;

}LQNode;  

【1】int Dingpiao(LQNode *head)//直接订票函数

1.根据航班号判断订票的航班

判断是否存在此航班

2.1若不存在,从新输入调用函数本身Dingpiao(head);

2.2有该航班

       请输入姓名(拼音)和票数

          判断机票是否都售完(数余票数)       

   3.1该航班无余票(票数为0),请耐心等待QueueAppend(p,xname,xnp);

   3.2输出可选座位号

3.3余票不足!输入1先定部分机票,输入0则等票!

4.4若输入1,则调用部分订票函数BfDingpiao(p,xname,xnp-j)  

4.5若输入0,则调用入队列等待函数QueueAppend(p,xname,xnp);        

【2】int QueueGet(LQNode *p)    //出队列订票

    n=0; //判断是否需要向队列依次询问订票

  函数被调用,则还有机票

  输出队首等待订票人姓名和票数 

  1.1如票足够,则输出票的座位号给用户选择

    选完之后,将座位号对应的票标记为已售。

  1.2若有票但比等票人定的票少

  2.1余票不足!输入1先定部分机票,输入0则等票!:

3.1若输入1,则调用部分订票函数BfDingpiao(p,xname,xnp-j) ,并修改订票人的订票数。 

3.2若输入0,则该等票者继续等票,向队列后面询问;

         直至队尾或没有票为止。

【3】int Tuipiao(LQNode *head)

退票函数,可根据用户的选择退一张或多张票,还可选择退票的座位号。

{

  int i,j,n,m;

  j=0;

  int number;

  char name[20];

  LQNode *p;//航班

  p=head;

  printf("\t\t请输入航班号:");

    scanf("%d",&number);

    while(p->next!=NULL&&p->next->Air.fnumber!=number)p=p->next;

    printf("\t\t请输入姓名(拼音):");

    scanf("%s",name);

    for(i=0;i<p->next->Air.jpshu;i++)//MaxStackSize

    if(strcmp(p->next->Air.ticket[i].name,name)==0)j++;

    if(j>1)

    {

        printf("\t\t你订了%d张机票,其座位号分别为:",j);

        for(i=0;i<p->next->Air.jpshu;i++)//MaxStackSize

        if(strcmp(p->next->Air.ticket[i].name,name)==0)

        printf("%d ",i+1);

            printf("\n\t\t请输入退票数:");

            scanf("%d",&n);

        printf("\t\t请输入退票的座位号:");

        for(i=0;i<n;i++)

        {

            scanf("%d",&m);

            p->next->Air.ticket[m-1].biaoji=0;

         }

    }

    else if(j==1)

    {

        printf("\t\t请输入退票的座位号:");

        scanf("%d",&m);

        p->next->Air.ticket[m-1].biaoji=0;

    }

  if(p->next->Air.Q.count!=0)QueueGet(p);//调用出队列函数(已确定航班)

    menu(head);

  return 0;

}

三、调试分析

      1.调试过程中遇到的主要问题是如何解决的;

  (1)使用链表时,和其他很多同学一样,容易将带头结点的链表和不带头结点的链表混淆,造成内存不可读或写的错误,经过对课程的回顾,及老师在课堂上的提醒注意,我终于改好了bug。

  (2)第一次给老师检查时,只是初步实现了题目要求的功能,进过老师的在三指导,程序越来越健壮和功能齐全,而且也更符合客观的情况。

2.对设计和编码的回顾讨论和分析;

总的来说,这个程序写的有点复杂,随着老师要求的不断完善,需要更多的添加和修改。好在老师立足于我写的代码,帮助我想办法完善程序,给我更好的完善程序的idea,说以此程序写的挺顺利,就只是其中变量多次多处被用到,要全局的改好程序需要了些许时间。

3.时间和空间复杂度的分析;

【1】int message(LQNode *head)//存储航班信息的线性表

时间O(1),空间O(n*n)

【2】int Dlmessage(LQNode *head)//删除航班信息

时间O(n),  空间O(1)

【3】int Ismessage(LQNode *head)//链表后插入航班信息

时间O(1),空间O(n)

【4】int Chmessage(LQNode *head)//链表中修改航班信息

   时间O(n),  空间O(1)

【5】int Semessage(LQNode *head)//航班查询

    时间O(n),  空间O(1)

【6】int HbSearch(LQNode *head)//航班

    时间O(n),  空间O(1)

【7】int SaSearch(LQNode *head)//起点

    时间O(n),  空间O(1)

【8】int EaSearch(LQNode *head)//终点

    时间O(n),  空间O(1)

【9】int TmSearch(LQNode *head)//日期

    时间O(n),  空间O(1)

【10】int Dingpiao(LQNode *head)//订票业务

    时间O(1),  空间O(1)

【11】int Qumessage(LQNode *head)//排队等票

    时间O(1),  空间O(1)

【12】int Cxmessage(LQNode *head)//查询订票信息

    时间O(1),  空间O(1)

4.改进设想;

       程序能实现很多的功能,也有改进空间

【1】:更符合实际的函数添加

       【2】:更简洁的代码

5.经验和体会等。

多动手编程,才能熟练灵活的掌握C语言基础知识,才能更好的理解掌握数据结构的精髓。从而避免基础语法错误,让代码变得更简洁高效。如此才能准确高效的解决问题。在今后的编程过程中要更注重代码的熟练掌握,多的温习代码思想,多的动手编程。还要多留心观察生活,体验生活,让自己的更加的具有实际可用性。

四、用户手册(即使用说明)

   完全按照提示输入。若出现不可预料的错误,请重新来过。

五、运行结果

运行环境:codeblocks

运行后的界面(主菜单)

测试数据:5

 **输入不符合要求时,程序非正常结束

****在输入完后,核对输入是否要求,如若不然提示暂无此业务,重新输入

(已改正)测试数据:1

测试数据:2

测试数据:依次输入2       1        4

载入,删除和查询功能正常

经测试插入和修改功能也正常。

  测试数据:依次输入0       2        1

航班号1已被删除,看程序是否会非正常终止

经测试程序仍正常进行,其他查询方式也都正确

测试数据:依次输入0       3        1        2

查看订票功能:

选择座位号时,非法多输入数据4

发现程序订票功能多循环一次,程序仍正常运行

经验证系统的订票,退票功能均可正常运行,出现非法输入时,也能继续正常运行,程序有一定的健壮性。

只是当需要整形输入航班号时,若输入英文字母,则会死循环。

暂不知如何避免(只能加以提醒注意)

六、源程序清单

https://wenku.baidu.com/view/c91fa69f6bdc5022aaea998fcc22bcd127ff4245

原文地址:https://www.cnblogs.com/XDJjy/p/3006020.html