天天看點

實習五 航空訂票系統 - 雨鈍風輕

實習五 航空訂票系統

一、需求分析

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

實習五 航空訂票系統 - 雨鈍風輕