学习队列、栈的经典案例--Re:停车场管理模拟修改版

来源:互联网 发布:xampp apache无法启动 编辑:程序博客网 时间:2024/04/30 05:15
  测试空间旗下大头针出品    
   这个程序既有链表,还有队列,还有顺序栈,是学习的时候的非常好的资料,下面我把改整过的程序给大家分享一下。基本的上能够运行通过了,可能还有不太合理的地方,希望大家能够多提建议共同改进。
#include <stdio.h>
#include<stdlib.h>

typedef struct {
        char tag; //到达、离去标志,'A'代表到达,'D'表示离去,'E'表示输入结束
        int num;  //汽车车牌号吗
        int time; //到达或离去时刻
} car;        // 汽车数据类型

typedef struct {
        car *base;
        car *top;
        int size;//当前已分配的栈中元素的个数
} Stack;    

 
typedef struct Node *QueuePtr;
struct Node {
        car a;                //停放在便道上的汽车
        QueuePtr next;  
} Node;                     //停车场外便道的一个结点

typedef struct {
        QueuePtr front;//链队列的头指针
        QueuePtr rear;//链队列的尾指针
} Queue;                         //停车场外的便道类型(队列)

Queue Q;
Stack Park, TempPark;
int fee,n;//全局变量n的作用是车辆的个数

//有关栈(停车场和临时停车场)的一些操作

//构造一个空栈
bool InitStack( Stack *s)
{
   (*s).base=(car *)malloc(n*sizeof(car));//(*s).base =
     if(!(*s).base) return false;
     (*s).top = (*s).base;
     (*s).size = n;
     return true;
}

//若栈不空,则用e返回栈顶元素,并返回true,否则返回false
bool GetTop( Stack s, car e)
{
     if(s.top==s.base) return false;
     e = *(s.top-1);
     return true;
}

//若栈不空,则删除s的栈顶元素,用e返回其值,并返回true;否则返回false
bool pop( Stack *s, car *e)
{
     if((*s).top==(*s).base)
   return false;
     *e = *(--(*s).top);
  printf("有车开走了/n");
  printf("车牌号码为%d/n",(*e).num);
     return true;
}

//若栈不满,则插入元素e为新的栈顶元素,并返回true;否则返回false
bool push( Stack *s, car e)
{
     if(((*s).top-(*s).base)==(*s).size) return false;
 
     *((*s).top)++ = e;
  printf("压栈成功,进入车厂了/n");
     return true;
}


 
//有关队列(停车场外的便道)的一些操作

//构造一个空队列
bool InitQueue(Queue *q)
{
     (*q).front=(*q).rear=(QueuePtr) malloc(sizeof(Node));
     if(!(*q).front) return false;
     (*q).front->next=NULL;
     return true;
}

//撤销队列
bool DestroyQueue(Queue *q)
{
     while((*q).front) {
                    (*q).rear=(*q).front->next;
                    free((*q).front);
                    (*q).front=(*q).rear;
     }
     return true;
}

//插入元素e为新的队尾元素
bool EnQueue(Queue *q, car e)
{
     QueuePtr p;
     p = (QueuePtr) malloc(sizeof(Node));
     if(!p) return false;                //存储空间分配失败
     p->a = e;
     p->next = NULL;
     (*q).rear->next=p;
     (*q).rear = p;
  printf("进入便道的车辆的号码为%d/n",(*p).a.num);
     return true;
}

//若队列不空,则删除q的队头元素,用e返回其值,并返回true;否则返回false
bool DeQueue(Queue *q, car *e)
{
     if((*q).front==(*q).rear) return false;
     QueuePtr p;
     p = (*q).front->next;
     *e = p->a;
     (*q).front->next = p->next;
     if((*q).rear==p) (*q).rear=(*q).front;
  printf("便道上的车辆驶入停车场了/n");
  printf("驶入停车场的便道上的车辆的号码为%d/n",(*e).num);
     free(p);
     return true;
}

//其它函数

//初始化
void Initialization()
{
   
     printf("*******************************************************************************/n/n");
     printf("*                           停车场管理模拟程序                                */n/n");
     printf("*******************************************************************************/n/n");
   
     printf("请确认停车场的容量:");
     scanf("%d",&n);//
     InitStack(&Park);
     InitStack(&TempPark);
     InitQueue(&Q);
     printf("        To input the auto information here:");
}
//查找栈中是否有与e牌号相同的汽车,若有,则返回true,否则返回false
bool check( Stack s, car e)
{
     car *temp=s.base;
     while((temp!=s.top) && (temp->num!=e.num)) temp++;
     if(temp==s.top)
   return false;
     else
   return true;
  
}

//对车辆信息进行处理的程序
bool process(car a)
{
     car e,tem;
     if(a.tag=='A')
  {
     //把车辆驶入停车场,车场中的号码不许是不相同的
                    if((int)(Park. top-Park.base)<Park.size)//Park是谁啊?
     {
      if(!check(Park, a))
      {
      printf("可以进入停车场的/n");
      push(&Park, a);
      }
      else
      {
       printf("车牌号相同的车辆是不合理的,请重新输入/n");
       return false;
      }
     }
     //如果车库满了,则驶入便道,车场中的号码不许是不相同的
                    else 
     {
      if(!check(Park, a))
      { 
       printf("进入便道等候/n");
       EnQueue(&Q,a);
      }
      else
      {
       printf("车牌号相同的车辆是不合理的请重新输入/n");
       return false;
      }

     }
     }
     else
     {
    if( !check(Park, a))
    {
     printf("输入错误,停车场中没有这辆车,请重新输入!/n");
     return false;
    }
    else
     printf("停车场上有这辆车,你可以开走了!/n");
    //下面车厂上有你输入的车的情况:
    //有两种情况:1.车在栈顶即最南端的情况
    //2.车辆在中间乃至栈底的情况,在栈中间还要挪车
    if(a.num==(Park.top-1)->num)
    {
     pop(&Park, &e);
     printf("停车厂中最南端,也就是栈顶的车辆开走了/n");
    }
    else
    {
     //把车库中的车挪出来,一边你的车开走
     do{
      if(pop(&Park, &tem))
      {
       printf("你得挪车到另一个栈中/n");
          printf("你的车牌号为%d/n",tem.num);
      }
      push(&TempPark, tem);
     }while(a.num!=(Park.top-1)->num);
     pop(&Park, &e);
     //其他车辆还要按照原来的次序放到车库里面
     do {
      pop(&TempPark, &tem);
      push(&Park, tem);
     }while(TempPark.top!=TempPark.base);
    }
         fee = a.time-e.time;
         printf("第%d号车的费用是:%d/n", a.num, fee);
  //当车满的情况下,便道才会有汽车,
   if(Q.front!=Q.rear)
  {
                   DeQueue(&Q, &tem);
                   push(&Park, tem);
  }

  }
  //停车场上有空位了,这个时候如果便道上有车可以让其装进停车场
   
 return true;
}

//以下为主函数

int main()
{
     Initialization();
     car c;
  fflush(stdin);
     scanf("%c%d%d", &c.tag, &c.num, &c.time);
     if(c.tag!='A' && c.tag!='D' && c.tag!='E')
  { printf("输入错误,请重新输入!/n");
     scanf("%c%d%d", &c.tag, &c.num, &c.time);
  }
     while(c.tag!='E')
     {
                        process(c);
      fflush(stdin);
      scanf("%c%d%d", &c.tag, &c.num, &c.time);
     
     }
     printf("程序结束/n");
     return 0;
}
参考资料:

参考一:停车场管理模拟源程序

参考2:停车厂模拟程序的三种常见错误以及解决方法 

 
原创粉丝点击