栈和队列:停车场管理
程序员文章站
2022-05-04 16:26:17
...
一、程序运行环境
1、操作系统: Windows 10 X64
2、IDE:Visual Studio 2019
二、问题描述
三、程序设计思路
(1)确定解决问题所使用的数据结构:以栈分别模拟停车场和为给要离去的汽车让路而从停车场退出来的汽车,以队列模拟车场外的便道。栈以顺序存储结构实现,队列以链式结构实现。
(2)定义Car结构体,用于实现栈的顺序存储结构,包括汽车号码、状态(到达/离开)、到达时间、抵达时间以及在停车场内停留时间,以便于后续相关计算。
struct Car
{
int number;
char aord;
int atime;
int dtime;
int dutime;
};
(3)定义结构体WCar,用于实现队列的链式存储结构,包括汽车号码、状态(到达/离开)、到达时间、抵达时间、以及指向下一个结点的指针。
struct WCar
{
int number;
char aord;
int atime;
int dtime;
WCar* next;
};
(4)分别实现栈和队列的基本功能:定义Stack类,实现初始化、入栈、出栈、查找等功能。定义Queue类,实现初始化、入队、出队等功能。
class Stack
{
private:
Car* base, * top;
int count;
public:
Stack()
{
count = 0;
base = new Car[n];
top = base;
}
int num()
{
return count;
}
int find(int x)
{
int i = 0;
Car* p=base;
while (p->number != x)
{
p++;
i++;
}
return i;
}
int getatime(int x)
{
return base[x].atime;
}
int Push(Car e)
{
top->aord = e.aord;
top->atime = e.atime;
top->dtime = e.dtime;
top->dutime = e.dutime;
top->number = e.number;
top++;
count++;
return count;
}
Car Pop()
{
Car p;
count--;
top--;
p = *top;
return p;
}
};
class Queue
{
private:
WCar* head,*rear;
public:
Queue()
{
WCar* p = new WCar;
p->number = 0;
p->next = NULL;
head = rear=p;
}
int Inqueue(WCar a)
{
WCar* p = new WCar;
p->aord = a.aord;
p->atime = a.atime;
p->dtime = a.dtime;
p->next = NULL;
p->number = a.number;
rear->next = p;
rear = p;
head->number ++ ;
return head->number;
}
Car Dequeue(Car a)
{
WCar* q;
Car p;
if (head == rear)exit(0);
q = head->next;
head->next = q->next;
p.aord = 'A';
p.atime=p.dtime = a.dtime;
p.dutime = 0;
p.number = q->number;
delete q;
head->number--;
return p;
}
int Getnumber()
{
return head->number;
}
};
(5)准备工作完成后,接下来梳理相关算法:首先判断输入的是‘A’或’D‘,若输入’A’,判断是否超过停车场容量n,超过通过Inqueue函数入队列,反之通过Push函数入栈;若输入‘D’,通过find函数找到该辆汽车所处位置以及进入停车场的时间,从而计算出停留时间,停车场内该辆汽车后的汽车出栈,进入另一栈,待该辆汽车出栈后另一栈汽车再依次入栈,并队列中第一辆汽车通过Dequeue函数出队入栈。
int main()
{
char c;
Stack s1, s2;
Queue h;
Car a; WCar b;
cin >> c >> c >> a.aord>>c>>c;
while (a.aord == 'A' || a.aord == 'D')
{
if (a.aord == 'A')
{
if (s1.num() <n)
{
cin >> a.number>>c>>a.atime>>c;
a.dtime = a.atime;
a.dutime = 0;
s1.Push(a);
cout << "汽车到达停车场位置:"<<s1.num()<<endl;
}
else
{
b.aord = 'A';
cin >> b.number >> c >> b.atime >> c;
b.dtime = b.atime;
b.next = NULL;
cout<< "汽车到达便道位置:"<<h.Inqueue(b)<<endl;//入队列
}
}
if (a.aord == 'D')
{
Car b;
cin >> a.number >> c >> a.dtime >> c;
int i = s1.find(a.number);
a.dutime = a.dtime - s1.getatime(i);//得到该车进入的时间
while (s1.num() != (i + 1))
{
b=s1.Pop();
s2.Push(b);
}
cout << "在停车场内停留时间:"<<a.dutime<<" "<<"需交停车费:"<<a.dutime<<endl;
s1.Pop();
while (s2.num() != 0)
{
b = s2.Pop();
s1.Push(b);
}
if (h.Getnumber()!=0&& s1.num()<n)s1.Push(h.Dequeue(a));//队列第一位进入栈
}
cin >> c >> c >> a.aord >> c>>c;
}
}
四、注意事项
①判断循环结束:应该先在输入字母时进行判断,若为’E’,则结束输入。在每一次循环结束后,也需要再对输入字母进行一次判断。
②判断便道上是否有汽车要进入:需要同时满足停车场栈内有一个空位且队列中有汽车,若没有对这两个同时进行限制的话,结果将出现错误。不必担心停车场栈内多个空位而队列中有汽车问题,因为队列中有汽车的前提是停车场栈内已满。
if (h.Getnumber()!=0&& s1.num()<n)s1.Push(h.Dequeue(a));